为何LIMIT 10比LIMIT 100执行慢?附执行计划对比分析
为什么LIMIT 10比LIMIT 100执行慢?优化方案解析
问题根源:查询优化器的计划选择偏差
这是典型的优化器基于LIMIT大小做出错误计划选择的案例,核心原因是优化器对符合条件的记录数量估计有误:
- 当
LIMIT 10时,优化器认为:“按dt_rssj的索引(i_T_JDRY_dt_rssj)扫描T_JDRY,逐个关联T_JCYQ找符合条件的记录,应该很快能凑够10条”。但实际情况是,符合T_JCYQ过滤条件的记录极少(最终只返回3条),导致优化器被迫扫描了15万+条T_JDRY记录,每条都要去查询T_JCYQ,绝大多数都不符合过滤条件,所以耗时飙升到3秒多。 - 当
LIMIT 100时,优化器重新评估成本:“先把T_JCYQ里符合所有过滤条件的记录找出来(虽然要扫全表,但符合条件的只有3条),再关联T_JDRY取数据,最后排序”的成本更低,所以选择了先处理T_JCYQ的计划,实际执行只花了60多毫秒。 - 移除LIMIT后,优化器不再优先考虑“快速获取少量数据”的短平快计划,会选择更适合全量数据的高效关联顺序;删除
i_T_JDRY_dt_rssj索引后,优化器没办法走排序索引的计划,只能选择更合理的关联路径,所以速度也显著提升。
优化方案
针对这个场景,有几个实用的优化方向:
1. 强制调整关联顺序(最直接)
重写SQL,明确从过滤条件更多的T_JCYQ表出发进行关联,引导优化器优先处理T_JCYQ的过滤逻辑:
EXPLAIN (analyze,buffers) SELECT jdry.c_bh AS rybh, jcyq.c_bh, jdry.c_xm, jdry.c_jdrybm, jcyq.c_jdsbm, jcyq.c_bmbm, jdry.c_fq, jdry.c_fj FROM db_szgl.T_JCYQ jcyq JOIN db_ggfw.T_JDRY jdry ON jdry.c_jdrybm = jcyq.c_jdrybm WHERE jcyq.c_sfyx <> '0' AND jcyq.c_dqspjg IS NULL AND jcyq.c_lx = '01' AND jcyq.c_dqspzt = '01' AND jcyq.c_jdsbm = '530104' ORDER BY jdry.dt_rssj DESC LIMIT 10 OFFSET 0
这种写法会让优化器更倾向于先筛选T_JCYQ的符合条件记录,再关联T_JDRY,避免无效的大量扫描。
2. 给T_JCYQ建立针对性复合索引
给T_JCYQ的过滤字段建立复合索引,让优化器可以快速定位符合条件的记录,不用全表扫描:
CREATE INDEX idx_jcyq_filter ON db_szgl.T_JCYQ (c_jdsbm, c_lx, c_dqspzt, c_sfyx) WHERE c_dqspjg IS NULL;
这个索引包含了所有过滤条件,并且通过WHERE子句限定了c_dqspjg IS NULL的场景,进一步缩小索引范围,提升查询效率。
3. 更新统计信息,修正优化器估计
如果优化器的统计信息过时,会导致它错误估计符合条件的记录数。执行以下命令更新表的统计信息:
ANALYZE db_szgl.T_JCYQ; ANALYZE db_ggfw.T_JDRY;
更新后,优化器能更准确地判断哪种执行计划成本更低,从而自动选择更优的路径。
4. 禁用不合适的索引(可选)
如果i_T_JDRY_dt_rssj索引在这个查询里经常导致糟糕的执行计划,且该索引不是其他业务必须的,可以考虑删除它;或者使用PostgreSQL的pg_hint_plan插件,通过hint强制不使用该索引:
EXPLAIN (analyze,buffers) SELECT /*+ IndexScan(jdry none) */ jdry.c_bh AS rybh, jcyq.c_bh, jdry.c_xm, jdry.c_jdrybm, jcyq.c_jdsbm, jcyq.c_bmbm, jdry.c_fq, jdry.c_fj FROM db_ggfw.T_JDRY jdry, db_szgl.T_JCYQ jcyq WHERE jdry.c_jdrybm = jcyq.c_jdrybm AND jcyq.c_sfyx <> '0' AND jcyq.c_dqspjg IS NULL AND jcyq.c_lx = '01' AND jcyq.c_dqspzt = '01' AND jcyq.c_jdsbm = '530104' ORDER BY dt_rssj DESC LIMIT 10 OFFSET 0
内容的提问来源于stack exchange,提问作者dodo
相关产品推荐
相关产品推荐

