问题描述
一条相似的SQL语句,变量值不同,执行计划不同。
SQL如下:
select order_no from OWNER.TAB_NAME where patient_id = '10221178' and ORDER_CONFIRM_TIME > SYSDATE - 120;(异常)
select order_no from OWNER.TAB_NAME where patient_id = '10221178' and ORDER_CONFIRM_TIME > SYSDATE - 150;(正常)
专家解答
120的trc文件可以看到成本最低的是bit map and的执行路径:
1. IDX_ORDER_ORDER_CONFIRM_TIME范围扫描的成本是694.69,索引的选择率是1.4638e-04
Access Path: index (RangeScan)
Index: IDX_ORDER_ORDER_CONFIRM_TIME
resc_io: 694.00 resc_cpu: 7033121
ix_sel: 1.4638e-04 ix_sel_with_filters: 1.4638e-04
Cost: 694.69 Resp: 694.69 Degree: 1
2. IDX_ORDER_PATIENT_ID范围扫描的成本是15.02
Access Path: index (AllEqRange)
Index: IDX_ORDER_PATIENT_ID
resc_io: 15.00 resc_cpu: 165625
ix_sel: 2.6288e-06 ix_sel_with_filters: 2.6288e-06
Cost: 15.02 Resp: 15.02 Degree: 1
3. 两个索引bit map and之后的成本是13,优化器选择了cost最低的bit map and执行计划
Access path: Bitmap index - accepted
Cost: 13.21 Cost_io: 12.01 Cost_cpu: 12299390 Sel: 3.8236e-10
Not believed to be index-only
150的trc文件中,成本最低是是IDX_ORDER_PATIENT_ID范围扫描:
1. IDX_ORDER_ORDER_CONFIRM_TIME范围扫描的成本变了,从上面的694.69变为888.88,索引的选择率也从1.4638e-04变为1.8733e-04,
应该就是这里的索引的成本增加,导致bitmap and之后的成本比单独IDX_ORDER_PATIENT_ID范围扫描的成本略高,因此选择了成本最低的IDX_ORDER_PATIENT_ID范围扫描的执行计划
Access Path: index (RangeScan)
Index: IDX_ORDER_ORDER_CONFIRM_TIME
resc_io: 888.00 resc_cpu: 8999327
ix_sel: 1.8733e-04 ix_sel_with_filters: 1.8733e-04
Cost: 888.88 Resp: 888.88 Degree: 1
2. IDX_ORDER_PATIENT_ID范围扫描的成本是15.02
Access Path: index (AllEqRange)
Index: IDX_ORDER_PATIENT_ID
resc_io: 15.00 resc_cpu: 165625
ix_sel: 2.6288e-06 ix_sel_with_filters: 2.6288e-06
Cost: 15.02 Resp: 15.02 Degree: 1
3. bit map and的成本是15.27
Access path: Bitmap index - rejected
Cost: 15.27 Cost_io: 14.01 Cost_cpu: 12906636 Sel: 4.8933e-10
至于为什么两个执行计划不一样,应该和IDX_ORDER_ORDER_CONFIRM_TIME索引选择率变化导致bit map的成本增加有关。