← 中文资源

简体中文版本

在 CI 中检测查询计划回归

把关键查询的 EXPLAIN 输出保存为基准文件,计划出现顺序扫描或成本上升时让 CI 失败。

阅读英文原文

概述

查询规划器可以为同一条 SQL 选择任何返回相同结果的计划。当索引被删除、统计信息变化或版本升级改变成本常数时,计划可能在没有任何代码改动的情况下退化。基准计划测试把少量关键查询的执行计划当作契约:允许变更,但必须显式审查。

步骤

  1. 用具有代表性行数的种子数据初始化测试库,并执行 ANALYZE,空表上的计划没有参考价值。
  2. 用 EXPLAIN (COSTS OFF) 捕获计划并写入基准文件,再用 diff 比对:
psql "$TEST_DATABASE_URL" -X -q -A -t \
  -c "EXPLAIN (COSTS OFF) SELECT o.id FROM orders o WHERE o.tenant_id = 42 AND o.status = 'open' ORDER BY o.created_at DESC LIMIT 20" \
  > plans/orders_open.plan
diff -u plans/orders_open.expected plans/orders_open.plan
  1. 计划不一致时让 CI 失败,并输出差异,要求作者修复回归或显式更新基准文件。
  2. 只在解释变更的同一个 PR 中重新生成基准文件,禁止自动更新。

验证

预期删除索引后差异中出现 Seq Scan on orders,CI 失败并附带计划对比;恢复索引后差异为空、构建通过。升级 PostgreSQL 大版本后应重新生成全部基准文件,并在目录中记录版本。

注意事项

  • COSTS OFF 隐藏成本估算,形状相同但成本暴涨的计划不会被发现,必要时对最重要的两三条查询额外校验 JSON 成本。
  • 只覆盖 5 条左右真正影响延迟的查询,全量覆盖会带来大量噪音。
  • CI 镜像必须固定 PostgreSQL 版本和种子脚本版本。
  • 禁止自动接受计划变更,人工审查才是这项测试的价值所在。