哪个查询计划更优?关于两个索引执行计划的性能判断疑问
为什么查询优化器偏好第二个索引?
先拆解你的查询逻辑:要从COD_PONTO=2085、ST_BOMBA为ON/OFF的记录里,按ST_BOMBA、Q_BOMBA、SEQUENCIAL分组,找出每组最新的HORA_LEIT,再取其中最新的那一组。
对比两个索引的工作方式:
索引ix_1的执行逻辑
ix_1的键列是cod_ponto, St_bomba,包含了分组和计算MAX需要的所有字段。执行时:
- 先定位到
cod_ponto=2085的所有ON/OFF记录 - 按
ST_BOMBA、Q_BOMBA、SEQUENCIAL分组,计算每组的MAX(HORA_LEIT) - 把所有分组的MAX值排序,取TOP1
这个过程必须遍历完所有符合条件的记录,完成全部分组聚合后才能排序,当符合条件的记录量较大时,聚合和排序的CPU、IO成本都会很高。
索引ix_2的执行逻辑
ix_2的键列是cod_ponto, hora_leit,记录按cod_ponto分组后,再按hora_leit从大到小排列(优化器可利用索引的有序性做反向扫描)。执行时:
- 定位到
cod_ponto=2085的记录,直接从hora_leit最大的那条开始遍历 - 每遍历一条,就检查它所属的分组(
ST_BOMBA、Q_BOMBA、SEQUENCIAL组合)是否已经被确认存在 - 一旦找到第一个能确定是
MAX(HORA_LEIT)对应的分组,就可以直接返回结果,不需要遍历所有符合条件的记录
这种“提前终止”的逻辑,在数据分布合适时(比如最大的hora_leit对应的分组只需要扫几条记录就能确认),成本会远低于ix_1的全量聚合+排序。
优化器选ix_2的核心原因
优化器是基于统计信息预估成本的:
- 如果统计信息显示,
cod_ponto=2085的ON/OFF记录中,最大的hora_leit对应的分组可以通过极少量的IO找到,那ix_2的预估成本会远低于ix_1 - 反之,如果你的数据中分组数极少(比如只有几个分组),ix_1的聚合成本可能更低,但优化器根据统计信息判断ix_2的路径更高效
你觉得ix_1更优,可能是忽略了ix_2的“提前终止”特性——它不需要处理所有数据就能拿到结果。如果想验证,可以实际跑一下两个查询(用WITH (INDEX(ix_1))和WITH (INDEX(ix_2))强制指定索引),对比实际的CPU、IO耗时,而不是只看执行计划的预估成本。
内容的提问来源于stack exchange,提问作者Book Writter
相关产品推荐
相关产品推荐

