直方图对执行计划的影响

 

SQL> create table test_for_col   as select rownum a,rownum b from dual connect by level<=20000 ;
Table created.
SQL> update test_for_col set a=20000 where a between 10 and 20000 ;
19991 rows updated.
SQL> commit;
Commit complete.
SQL> create index idx_test on test_for_col(a);
Index created.
SQL> analyze table  test_for_col compute statistics;
Table analyzed.
SQL> analyze index idx_test compute statistics ;
Index analyzed.
SQL>  set autotrace trace exp ;
SQL> set linesize 150 ;
SQL>  select * from test_for_col where a= 1 ;
Execution Plan
----------------------------------------------------------
Plan hash value: 3390667667

--------------------------------------------------------------------------------------------
| Id  | Operation                   | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |              |  2000 | 12000 |     8   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TEST_FOR_COL |  2000 | 12000 |     8   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_TEST     |  2000 |       |     4   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("A"=1)  
SQL> select * from test_for_col where a= 20000 ;
Execution Plan
----------------------------------------------------------
Plan hash value: 3390667667

--------------------------------------------------------------------------------------------
| Id  | Operation                   | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |              |  2000 | 12000 |     8   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TEST_FOR_COL |  2000 | 12000 |     8   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_TEST     |  2000 |       |     4   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("A"=20000)

SQL> select a,count(*) from test_for_col group by a order by a ;

         A   COUNT(*)
---------- ----------
         1          1
         2          1
         3          1
         4          1
         5          1
         6          1
         7          1
         8          1
         9          1
     20000      19991

10 rows selected.

可以看出数据极度倾斜,并且在访问的时候给出了错误的执行计划。

现在修改分析命令构造直方图

SQL>  analyze table  test_for_col compute statistics for all indexed  columns ;

Table analyzed.

这句命令的意思是 统计这个表所有索引列的信息。并构造直方图

SQL> select num_rows, blocks, empty_blocks, avg_space, chain_cnt, avg_row_len
FROM DBA_TABLES
where wner = 'SYS'
AND TABLE_NAME = UPPER('test_for_col')  2    3    4  ;

  NUM_ROWS     BLOCKS EMPTY_BLOCKS  AVG_SPACE  CHAIN_CNT AVG_ROW_LEN
---------- ---------- ------------ ---------- ---------- -----------
     20000         39            0       1651          0          10

SQL> select num_distinct, low_value, high_value, density, num_buckets, last_analyzed, sample_size
     from dba_tab_columns
     where table_name = UPPER('test_for_col') ;  2    3

NUM_DISTINCT LOW_VALUE            HIGH_VALUE       DENSITY NUM_BUCKETS LAST_ANALYZE SAMPLE_SIZE
------------ -------------------- ------------------------ ----------- ------------ -----------
          10 C102                 C303             .000025          10 13-OCT-09          20000
       20000 C102                 C303              .00005           1 13-OCT-09          20000
     
NUM_DISTINCT   该列不同值的数量 
NUM_BUCKETS    柱状图的数量
SAMPLE_SIZE    采样的数量 可以使用SAMPLE子句来指定采样的百分比或者行数

重复刚才的实验

SQL> select * from test_for_col where a= 1 ;                                               
                                                                                           
Execution Plan                                                                             
----------------------------------------------------------                                 
Plan hash value: 3390667667                                                                
                                                                                           
--------------------------------------------------------------------------------------------
| Id  | Operation                   | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |              |     1 |     6 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TEST_FOR_COL |     1 |     6 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX_TEST     |     1 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
                                                                                           
Predicate Information (identified by operation id):                                        
---------------------------------------------------                                        
                                                                                           
   2 - access("A"=1)                                                                       
                                                                                           
SQL> select * from test_for_col where a= 20000 ;                                           
                                                                                           
Execution Plan                                                                             
----------------------------------------------------------                                 
Plan hash value: 170577590                                                                 
                                                                                           
----------------------------------------------------------------------------------         
| Id  | Operation         | Name         | Rows  | Bytes | Cost (%CPU)| Time     |         
----------------------------------------------------------------------------------         
|   0 | SELECT STATEMENT  |              | 19991 |   117K|    11  (10)| 00:00:01 |         
|*  1 |  TABLE ACCESS FULL| TEST_FOR_COL | 19991 |   117K|    11  (10)| 00:00:01 |         
----------------------------------------------------------------------------------         
                                                                                           
Predicate Information (identified by operation id):                                        
---------------------------------------------------                                        
                                                                                           
   1 - filter("A"=20000)                                                                   
                          
                         
看见已经给出了正确的执行计划           


                                                                              

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12474069/viewspace-616422/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12474069/viewspace-616422/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值