한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

游戏卡顿白皮书 › L12 数据库

执行计划变化导致查询变慢 Query plan regression (stats, parameter sniffing)

原因 ID db-plan-flip · 主责 运维团队·数据库运维 · 配合 研发团队·服务器开发

在含图示和实验的完整版中打开此卡片 →

代码没变,DB 却换了处理同一条查询的方式(执行计划),昨天 2 ms 的查询今天就变成几百 ms。

起因 统计信息自动更新、DB 重启、数据分布变化,让 DB 重新制定执行计划 → 结果 选中了不走索引的计划,同一条查询慢了几十到几百倍,连接被占住 → 画面表现 没有任何发布,某个功能的加载却突然变慢,其他请求也跟着等待

症状
操作延迟, 连不上/无限加载
因素
延迟, 停顿
谁会遇到
仅特定功能, 全服
何时出现
偶尔随机
负责方
主责 运维团队·数据库运维 · 配合 研发团队·服务器开发
研发团队要做的事
结果行数随参数值差异很大的查询,拆开写或考虑使用计划提示(hint),把查询设计成一定能走索引。
运维团队要做的事
监控慢查询和执行计划记录,固定好的计划(SQL Server 查询存储等),管理统计信息的更新时间。
监控图上
某一时刻起台阶式上升 · 各查询的平均执行时间
查看位置
定期收集同类查询的平均耗时,观察趋势。MySQL 看 events_statements_summary_by_digest 的 AVG_TIMER_WAIT,PostgreSQL 看 pg_stat_statements 的 mean_exec_time(12 及以下为 mean_time)。变慢前后的执行计划用 EXPLAIN 或 PostgreSQL 的 auto_explain 对比,SQL Server 用查询存储的“回归查询”(Regressed Queries)视图对比
确认依据
在没有发布的时间点,某条查询的平均耗时台阶式上升几十倍,该时间点与统计信息更新、DB 重启重合,执行计划也已改变
排除依据
执行计划没变却变慢,是数据量增长、锁等待或磁盘问题,锁等待看“热点行锁竞争”(db-hot-row)
确认手段
运维工具即可确认(无需游戏代码)
深入了解
SQL Server 会复用按第一次传入的参数值制定的计划(参数嗅探)。按只有几件物品的新角色制定的计划,用在有几万件物品的老角色身上就会大幅变慢,反过来的情况也很常见。重启清掉计划后恢复正常,过后又会再次变差。

出处

  1. Query Processing Architecture Guide Microsoft SQL Server
    参数嗅探:按编译、重新编译时传入的参数值制定执行计划
  2. Parameter Sensitive Plan Optimization Microsoft SQL Server
    数据分布不均匀时,缓存的单个计划无法适合所有参数值
  3. Monitor performance by using the Query Store Microsoft SQL Server
    统计信息、表结构、索引变化会让计划改变,计划缓存只保留最新的计划;用查询存储的强制计划固定好的计划,用“回归查询”(Regressed Queries)视图对比变慢的查询及其计划
  4. Statement Summary Tables MySQL
    events_statements_summary_by_digest:按同类查询统计的 COUNT_STAR、AVG_TIMER_WAIT(平均耗时)
  5. pg_stat_statements — track statistics of SQL planning and execution PostgreSQL
    每条语句的 calls、total_exec_time、mean_exec_time(平均执行时间)
  6. pg_stat_statements (PostgreSQL 12 Documentation) PostgreSQL
    12 及以前的列名为 total_time、mean_time
  7. auto_explain — log execution plans of slow queries PostgreSQL
    把耗时超过 auto_explain.log_min_duration 的查询的执行计划记入日志

相关原因

同一层:L12 数据库

其他层中同样导致“操作延迟”的原因

查看含图示和实验的原卡片