SCOTT@ prod>create table test2 as select * from emp;
SCOTT@ prod>create index ind_test2_empno on test2(empno);
SCOTT@ prod>analyze table test2 compute statistics;
|
SCOTT@ prod>set autotrace traceonly SCOTT@ prod>select * from test2 where empno=7788;
Execution Plan ---------------------------------------------------------- Plan hash value: 3801234157
-------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 87 | 2 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1 | 87 | 2 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | IND_TEST2_EMPNO| 1 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("EMPNO"=7788) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 0 consistent gets 0 physical reads 0 redo size 0 bytes sent via SQL*Net to client 0 bytes received via SQL*Net from client 0 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed |
|
SCOTT@ prod>begin for i in 1..10000 loop insert into test2 values(7788,'WARD','SALESMAN',7839,sysdate,3000,2000,20); end loop; end; / PL/SQL procedure successfully completed. SCOTT@ prod>commit;
SCOTT@ prod>select count(*) from test2;
COUNT(*) ---------- 10014 SCOTT@ prod>select count(*) from test2 where empno=7788;
COUNT(*) ---------- 10001 SCOTT@ prod> |
|
SCOTT@ prod>analyze table test2 estimate statistics; SCOTT@ prod>select * from test2 where empno=7788; 10001 rows selected. Execution Plan ---------------------------------------------------------- Plan hash value: 3801234157 -------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 715 | 23595 | 8 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST2 | 715 | 23595 | 8 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | IND_TEST2_EMPNO | 715 | | 3 (0)| 00:00:01 | -------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("EMPNO"=7788) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 0 consistent gets 0 physical reads 0 redo size 0 bytes sent via SQL*Net to client 0 bytes received via SQL*Net from client 0 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 10001 rows processed SCOTT@ prod> |
|
SYS@ prod>select t.table_name,t.NUM_ROWS,t.BLOCKS,t.AVG_ROW_LEN,i.index_name,i.CLUSTERING_FACTOR from dba_tables t,dba_indexes i where t.table_name=i.table_name and t.owner='SCOTT' and t.table_name='TEST2';
TABLE_NAME NUM_ROWS BLOCKS AVG_ROW_LEN INDEX_NAME CLUSTERING_FACTOR ---------- ---------- ------- ----------- --------------- ----------------- TEST2 10014 68 42 IND_TEST2_EMPNO 63 |
|
SCOTT@ prod>select column_name,num_distinct,num_buckets,histogram from user_tab_col_statistics where table_name='TEST2' and column_name='EMPNO';
COLUMN_NAME NUM_DISTINCT NUM_BUCKETS HISTOGRAM ------------------------------ ------------ ----------- --------------- EMPNO 14 1 NONE |
通常当查询结果小于3%-5%时,oracle会选择走索引。
本次查询全表数据10014行,查询结果数据10001行,属于行比例偏差较大的情况,以empno=7788条件查询时,走索引反而代价更高。需要为列建立柱状图。
|
SYS@ prod>exec DBMS_STATS.GATHER_TABLE_STATS('SCOTT', 'TEST2', method_opt => 'FOR COLUMNS empno'); PL/SQL procedure successfully completed. |
|
SCOTT@ prod>select column_name,num_distinct,num_buckets,histogram from user_tab_col_statistics where table_name='TEST2' and column_name='EMPNO';
COLUMN_NAME NUM_DISTINCT NUM_BUCKETS HISTOGRAM ------------------------------ ------------ ----------- --------------- EMPNO 14 14 FREQUENCY |
|
SCOTT@ prod>select * from test2 where empno=7788;
10001 rows selected. Execution Plan ---------------------------------------------------------- Plan hash value: 300966803 --------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 10001 | 332K| 18 (6)| 00:00:01 | |* 1 | TABLE ACCESS FULL| TEST2 | 10001 | 332K| 18 (6)| 00:00:01 | --------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("EMPNO"=7788) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 0 consistent gets 0 physical reads 0 redo size 0 bytes sent via SQL*Net to client 0 bytes received via SQL*Net from client 0 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 10001 rows processed
SCOTT@ prod> |
|
SCOTT@ prod>select * from test2 where empno=7499; Execution Plan ---------------------------------------------------------- Plan hash value: 3801234157 -------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 34 | 2 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1 | 34 | 2 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | IND_TEST2_EMPNO | 1 | | 1 (0)| 00:00:01 | -------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("EMPNO"=7499) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 0 consistent gets 0 physical reads 0 redo size 0 bytes sent via SQL*Net to client 0 bytes received via SQL*Net from client 0 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed |
这次执行计划选择了索引
|
1、通常当查询结果小于3%-5%时,oracle会选择走索引。当行比例偏差较大的时,需要为列建立柱状图。建立柱状图后,查询结果行比例较大时,会走全表扫描。查询结果比例小于3%-5%时,仍然走索引。 2、为列建立柱状图的另一种方法 SCOTT@ prod>analyze table test2 estimate statistics; SCOTT@ prod>analyze table test2 estimate statistics for columns empno; |
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29475508/viewspace-1264276/ ,如需转载,请注明出处,否则将追究法律责任。