zoukankan      html  css  js  c++  java
  • Oracle预估的基数算法

    SQL> create table t as select * from dba_objects;  
      
    Table created.  
      
    SQL> create index idx_t on t(object_id);  
      
    Index created.  
    
    
    SQL> BEGIN  
      2    DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'TEST',  
      3                                  tabname          => 'T',  
      4                                  estimate_percent => 100,  
      5                                  method_opt       => 'for all columns size auto',  
      6                                  degree           => DBMS_STATS.AUTO_DEGREE,  
      7                                  cascade          => TRUE);  
      8  END;  
      9  /  
    
    
    SQL> alter session set optimizer_features_enable='9.2.0';
    
    Session altered.
    
    
    SQL> explain plan for  select owner from t where object_id<1000;  
    
    Explained.
    
    SQL> select * from table(dbms_xplan.display());
    
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------------------------------------------
    
    --------------------------------------------
    Plan hash value: 1594971208
    
    ---------------------------------------------------------------------
    | Id  | Operation		    | Name  | Rows  | Bytes | Cost  |
    ---------------------------------------------------------------------
    |   0 | SELECT STATEMENT	    |	    |	958 | 10538 |	 26 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| T     |	958 | 10538 |	 26 |
    |*  2 |   INDEX RANGE SCAN	    | IDX_T |	958 |	    |	  4 |
    ---------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("OBJECT_ID"<1000)
    
    Note
    -----
       - cpu costing is off (consider enabling it)
    
    18 rows selected.
    
    
    那么这个958 Oracle是怎么估算的呢?
    Oracle预估的基数等于有效选择性*(num_rows-num_nulls)
    
    其中 有效选择性 ,< 的有效选择性算法为:
    
    (limit-low_value)/(high_value-low_value)
    
    
    
    
    set linesize 200
    SQL> select b.num_rows,
           a.num_distinct,
           a.num_nulls,
           utl_raw.cast_to_number(high_value) high_value,
           utl_raw.cast_to_number(low_value) low_value,
           (b.num_rows - a.num_nulls) "NUM_ROWS-NUM_NULLS",
           utl_raw.cast_to_number(high_value) -
           utl_raw.cast_to_number(low_value) "HIGH_VALUE-LOW_VALUE"
      from dba_tab_col_statistics a, dba_tables b
     where a.owner = b.owner
       and a.table_name = b.table_name
       and a.owner = 'TEST'
       and a.table_name = upper('T')
       and a.column_name = 'OBJECT_ID';  2    3    4    5    6    7    8    9   10   11   12   13   14  
    
      NUM_ROWS NUM_DISTINCT  NUM_NULLS HIGH_VALUE  LOW_VALUE NUM_ROWS-NUM_NULLS HIGH_VALUE-LOW_VALUE
    ---------- ------------ ---------- ---------- ---------- ------------------ --------------------
         73964	  73964 	 0	77085	       2	      73964		   77083
    
    
    那么估算为:
    SQL> 
    select ceil((1000-2)/77083*73964) from dual;SQL> 
    
    CEIL((1000-2)/77083*73964)
    --------------------------
    		       958
    
    Oracle 就是根据这个算法的
    

  • 相关阅读:
    Python 之 面向对象(一)
    Python 之 基础知识(五)
    javaweb 之 代理模式
    Python 之 基础知识(四)
    Python 之 基础知识(三)
    如何在非 sudo 用户下运行 docker 命令?
    Leetcode 55
    Leetcode 11
    Leetcode 466
    几个内存操作函数使用
  • 原文地址:https://www.cnblogs.com/zhaoyangjian724/p/3797928.html
Copyright © 2011-2022 走看看