本帖最后由 〇〇 于 2015-12-24 12:17 编辑
有如下查询,不加hint时,优化器自己选择的执行计划是走全表扫描,花费时间很长,
但加hint强制让大表走skip index时间很短,根据传统的理解,引导列上重复出现的值越少
走skip index的可能越大.但本查询中引导列的重复值也不多,且强制使用skip index后花费的时间
明显减少,在不加hint时,优化器为什么不能自己判断出走skip index后更快的执行计划呢?
哪位大侠能给个skipindex cost计算的公式?谢谢
本查询结构是一个有30条数据的小表,和一个4百万数据的大表关联,大表上有主键索引
主键索引中有两列 如(YMD,SERL_NO),YMD列就是前导列。具体查询和执行计划如下
1使用索引时
SQL_ID 4nr6cv01fxb4s, child number 0
-------------------------------------
SELECT /*+ INDEX_SS(T1 PK_RW_BI_FT_LT) */
T2.SERL_NO
,T1.SI_YMD
,T1.ST_YMD
,T1.ST2_YMD
,T1.SO_YMD
,T1.ACTU_DT
FROM MCS_HQ_READ.RW_BI_FT_LT_BAK T1
,MCS_HQ_READ.UP_LOAD_SERL10 T2
WHERE T1.SERL_NO = T2.SERL_NO
Plan hash value: 2981316369
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 29 |00:00:00.03 | 6060 |
| 1 | NESTED LOOPS | | 1 | 10 | 29 |00:00:00.03 | 6060 |
| 2 | TABLE ACCESS FULL | UP_LOAD_SERL10 | 1 | 29 | 29 |00:00:00.01 | 2 |
| 3 | TABLE ACCESS BY INDEX ROWID| RW_BI_FT_LT_BAK | 29 | 1 | 29 |00:00:00.03 | 6058 |
|* 4 | INDEX SKIP SCAN | PK_RW_BI_FT_LT | 29 | 1 | 29 |00:00:00.03 | 6032 |
----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("T1"."SERL_NO"="T2"."SERL_NO")
filter("T1"."SERL_NO"="T2"."SERL_NO")
2全表扫描时
SQL_ID c3shr653mx487, child number 0
-------------------------------------
SELECT T2.SERL_NO
,T1.SI_YMD
,T1.ST_YMD
,T1.ST2_YMD
,T1.SO_YMD
,T1.ACTU_DT
FROM MCS_HQ_READ.RW_BI_FT_LT_BAK T1
,MCS_HQ_READ.UP_LOAD_SERL10 T2
WHERE T1.SERL_NO = T2.SERL_NO
Plan hash value: 1553165350
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
---------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 29 |00:00:06.16 | 105K| 105K|
|* 1 | HASH JOIN | | 1 | 10 | 29 |00:00:06.16 | 105K| 105K|
| 2 | TABLE ACCESS FULL| UP_LOAD_SERL10 | 1 | 29 | 29 |00:00:00.01 | 2 | 0 |
| 3 | TABLE ACCESS FULL| RW_BI_FT_LT_BAK | 1 | 1379K| 3999K|00:00:03.96 | 105K| 105K|
---------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"."SERL_NO"="T2"."SERL_NO")
具体统计信息参考
索引统计
INDEX_NAME INDEX_TYPE BLEVEL LEAF_BLOCKS DISTINCT_KEYS AVG_LEAF_BLOCKS_PER_KEY AVG_DATA_BLOCKS_PER_KEY CLUSTERING_FACTOR NUM_ROWS
PK_RW_BI_FT_LT NORMAL 2 24675 3879361 1 1 3819111 3879361
表统计
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN SAMPLE_SIZE PARTITIONED
RW_BI_FT_LT_BAK 3999999 105977 0 0 0 190 3999999 NO
前导列YMD统计
COLUMN_NAME NUM_DISTINCT LOW_VALUE HIGH_VALUE DENSITY NUM_NULLS NUM_BUCKETS SAMPLE_SIZE HISTOGRAM AVG_COL_LEN
YMD 61 3230313431313030 3230313431323330 0.016393443 0 1 3999999 NONE 9