ゲームラグ白書 › L12 データベース
実行計画の変化によるクエリ遅延 Query plan regression (stats, parameter sniffing)
原因ID db-plan-flip · 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
図と実験のあるメインページでこのカードを開く →
コードは変わっていないのに、DBが同じクエリの処理方法(実行計画)を変えると、昨日2msだったクエリが今日は数百msになります。
なぜ 統計情報の自動更新、DBの再起動、データ分布の変化で、DBが実行計画を立て直す → すると インデックスを使わない計画が選ばれ、同じクエリが数十〜数百倍遅くなり、コネクションがふさがる → 画面では デプロイもなかったのに特定の機能のロードが急に遅くなり、他の要求まで待たされる
症状 入力遅延 , 接続不可・無限ロード
要因 遅延, ストール
誰に起きるか 特定の機能だけ, サーバー全体
いつ ときどきランダムに
担当 主担当 インフラチーム・DBインフラ · 副担当 ゲーム開発チーム・サーバー開発
ゲーム開発チームの対応 値によって結果の件数が大きく変わるクエリは分けて使うか、実行計画のヒントを検討、インデックスが確実に効くクエリの設計。
インフラチームの対応 スロークエリと実行計画の記録の監視、良い計画の固定(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)画面で比較 該当する場合 デプロイのなかった時刻に1つのクエリの平均時間が階段状に数十倍に上がり、その時点が統計情報の更新・DBの再起動と重なり、実行計画が変わっている 該当しない場合 実行計画は変わっていないのに遅くなったなら、データの増加、ロック待ち(db-hot-row)、ディスク側 確認手段 インフラのツールで確認(ゲームコード不要)
もっと詳しく SQL Serverは、最初に渡された値に合わせて立てた計画を再利用します(パラメータスニッフィング)。アイテムが数個しかない新規キャラクターで立てた計画が、アイテムを数万個持つ古いキャラクターに使われると大きく遅くなり、その逆もよくあります。再起動で計画が消えると正常に戻り、また悪化することもあります。
出典 Query Processing Architecture Guide Microsoft SQL Server パラメータスニッフィング:コンパイル・再コンパイル時に渡されたパラメータ値に合わせて実行計画を立てる Parameter Sensitive Plan Optimization Microsoft SQL Server データ分布が偏っていると、キャッシュされた1つの計画がすべてのパラメータ値には合わない Monitor performance by using the Query Store Microsoft SQL Server 統計情報・スキーマ・インデックスの変化で計画が変わり、プランキャッシュは最新の計画しか保持しない、クエリストアのプラン強制で良い計画を固定、「機能低下したクエリ」(Regressed Queries)画面で遅くなったクエリと計画を比較 Statement Summary Tables MySQL events_statements_summary_by_digest:同じ形のクエリごとのCOUNT_STAR・AVG_TIMER_WAIT(平均時間) pg_stat_statements — track statistics of SQL planning and execution PostgreSQL ステートメントごとのcalls、total_exec_time、mean_exec_time(平均実行時間) pg_stat_statements (PostgreSQL 12 Documentation) PostgreSQL 12まではカラム名がtotal_time・mean_time auto_explain — log execution plans of slow queries PostgreSQL auto_explain.log_min_durationより長くかかったクエリの実行計画をログに出力
あわせて読みたい原因
同じ層:L12 データベース
同じ症状(入力遅延)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る