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

ゲームラグ白書 › 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は、最初に渡された値に合わせて立てた計画を再利用します(パラメータスニッフィング)。アイテムが数個しかない新規キャラクターで立てた計画が、アイテムを数万個持つ古いキャラクターに使われると大きく遅くなり、その逆もよくあります。再起動で計画が消えると正常に戻り、また悪化することもあります。

出典

  1. Query Processing Architecture Guide Microsoft SQL Server
    パラメータスニッフィング:コンパイル・再コンパイル時に渡されたパラメータ値に合わせて実行計画を立てる
  2. Parameter Sensitive Plan Optimization Microsoft SQL Server
    データ分布が偏っていると、キャッシュされた1つの計画がすべてのパラメータ値には合わない
  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 データベース

同じ症状(入力遅延)を起こすほかの層の原因

図と実験のあるメインページでこのカードを見る