You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同一查询在两数据库中选用不同索引的原因及数据影响咨询

同一SQL在不同数据库执行计划差异的原因分析

问题背景

我编写了如下SQL查询语句,在两个数据内容不同的数据库(记为A和B)中执行时,得到的执行计划存在差异:

SELECT *
FROM   voucher_row_tab g,
       voucher_type_tab v
WHERE  g.company            = '12'
AND    (g.voucher_date BETWEEN to_date('2022-12-10', 'YYYY-MM-DD')  AND to_date('2023-12-10', 'YYYY-MM-DD'))
AND    (g.account      BETWEEN  '100'    AND '200')
AND    g.company            = v.company
AND    g.voucher_type       = v.voucher_type  
AND    v.simulation_voucher  != 'TRUE'
AND    'TRUE' = (SELECT TEST_API.CHECK (g.company, g.pc_id) FROM DUAL);

注:原SQL中AND ('2023-12-10', 'YYYY-MM-DD')存在语法错误,已修正为AND to_date('2023-12-10', 'YYYY-MM-DD')

两个数据库均已定义以下两个索引:

  • 索引1:<COMPANY, ACCOUNTING_PERIOD, ACCOUNTING_YEAR, VOUCHER_TYPE>
  • 索引2:<PC_ID, COMPANY, ACCOUNTING_YEAR>

数据库A选用索引1,数据库B选用索引2,请问造成该差异的原因是什么?数据内容是否会对此产生影响?

核心原因及分析

1. 统计数据差异是核心驱动

数据库优化器选择索引的核心依据是表和索引的统计数据,两个库的数据内容不同,导致统计信息(比如表的总行数、列的基数、数据分布区间、过滤条件的命中行数)完全不一致:

  • 对索引1:如果数据库A中company='12'的过滤条件能筛选出极小比例的行,优化器会判定通过索引1快速定位数据后,再处理后续关联、子查询的成本更低。
  • 对索引2:SQL中存在依赖pc_id的API调用子查询,数据库B的统计数据可能显示pc_id的分布更集中,或者通过索引2获取pc_id后,能大幅减少API的无效调用次数,整体成本更优。

2. 数据内容直接影响索引选择

数据内容的差异是根本因素:

  • 若数据库A中voucher_date和account的组合过滤返回的数据集极小,优化器会优先用包含COMPANY的索引1定位数据,再推进后续逻辑。
  • 若数据库B中满足company='12'且API返回TRUE的pc_id占比更高,或者pc_id的重复率低,优化器会认为通过索引2获取pc_id能更高效地匹配子查询条件,降低整体执行成本。

3. 其他潜在影响因素

  • 两个数据库的优化器参数(如optimizer_mode、optimizer_index_cost_adj)可能存在差异,导致成本计算逻辑不同。
  • voucher_type_tab的数据量、索引情况在两个库中不一致,会影响关联操作的成本评估,进而反向影响voucher_row_tab的索引选择。

结论

数据内容确实会直接影响执行计划的选择,核心原因是不同数据库的统计数据、数据分布、过滤条件的命中规模存在差异,导致优化器对两个索引的成本计算结果不同,最终选择了不同的执行路径。

内容的提问来源于stack exchange,提问作者lse23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 14:27:31