前月1か月の集計なのに重い|非パーティション表と並列フルスキャン

この記事で分かること

  • 前月1か月の集計なのに、他のテーブルと比べて明らかに遅いときの、まず疑う先
  • 初見・あまり使っていないテーブルほど、その差に気づきやすいこと
  • 日付パーティションのない巨大明細では、期間を狭くしても読む量が落ちにくいこと
  • 直近3か月を「1か月×3並列」に分けたときの、フルスキャン3本とスロット圧迫
  • 実行前の短いチェックと、待ち方・残し方へのつなぎ

結論(先に要点)

見た目は次のような SQL でも、いつも触っている表と比べて極端に遅いことがあります。

  • 前月1か月だけを対象にする
  • 月次の件数や金額を出す
  • SQL 自体は短い

「1年分なら重いのも分かる」と思いがちですが、実務で痛いのはここです。
前月のデータであっても、対象となるテーブルが大きな非パーティショニングされた詳細データである場合、他テーブル比で極端に遅くなる

初見のテーブルや、普段あまり使っていないテーブルで起きやすいです。
いつもの軽さの感覚が通じないので、「SQLが悪いのか?」と寄り道しやすい、という場面です。

さらに悪いのが、直近3か月が欲しいときの次の発想です。

3か月いっぺんは時間がかかりそうだから、1か月分の検索を3つに分割して並行実行しよう。

非パーティション表では、各本がだいたい フルスキャン相当 になります。
1本のフルスキャンが3本同時に走るので、スロットをまとめて食うことがあります。期間を分けたつもりが、負荷だけ倍増、というパターンです。

※ 本稿のプロジェクトID・データセット名・テーブル名・列名は説明用の仮名です。

体験のイメージ

初見、またはほとんど触ったことのない表に、「前月の件数を出すだけ」の SQL を流す。
いつものテーブルならすぐ返る感覚なのに、こちらは極端に遅い。
あとから定義を見ると、日付カラムでパーティション分割されていなかった——というパターンです。

1年分なら「まあ重いよな」で納得しやすいのですが
前月1か月でも、他のテーブルと比べて明らかに遅い場合と、その原因は対象のテーブルにあると気づきやすいです。

記事のポイントは「なぜフルスキャンになるか」の講義ではなく、非パーティション表かどうかを見抜くことが重要です。あわせて、3並列で悪化させないことです。

前月1か月でも、他テーブル比で極端に遅い表とは

相手はだいたい次の部類です。

特徴 現場での見え方
日付でパーティション分割されていない WHERE で前月に絞っても、読む量が落ちにくい
行数・データ量が大きい明細(生ログなど) 「1か月分の結果」でも裏で巨大な明細を噛まされている
日付列はあるが、絞り込みと噛み合っていない 意図と実際の読み方がズレる
ドライランのスキャン見込みが大きい 実行前に「前月なのに、他表より明らかに重い」と分かる

SQL が短いこと・対象期間が1か月であることと、読む量が小さいことは別です。

直近3か月:いっぺん vs 1か月×3並列

直近3か月分が欲しいとき、現場では次の二択になりがちです。

やり方 起きやすいこと
3か月を1本の SQL で集計 重い。ただしフルスキャンは(だいたい)1本
1か月×3本を並列実行 「早く終わるかも」と思いやすい。非パーティションなら フルスキャンが3本同時に発生する ことになり、スロットを同時に圧迫しやすい

「期間を分割して実行する」は、パーティションがある表では有効なことがあります。
無い表では、分けても読む量がほとんど減らず、並列にした分だけ資源を食う、という整理です。

並列で投げたくなったら、先に次を確認します。

  1. ドライランで、1か月分のスキャン見込みを見る
  2. それが表全体に近いなら、3並列は ほぼ同じ巨大スキャンが3本
  3. その場合は、いっぺんに1本で投げる/期間をさらに狭く試す/結果テーブル化や元表の設計を検討する、の方が安全なことが多い

実行前の短いチェック

  1. テーブル詳細で、パーティションの有無を見る
  2. ドライランで、前月1か月分のスキャン量を確認する
  3. 大きいなら、次を選ぶ
    • 期間をさらに狭くして試す(週・日など)
    • 重い前提で1本投げ、結果は履歴であとから見る
    • 「3か月欲しいから3並列」は、フルスキャン3本になっていないか疑う
    • 繰り返し使用する場合は結果テーブル化や元表の再設計を検討すること。

根本対策は、設計側のパーティション化や事前集計テーブルです。
「いま画面で待っているジョブ」への対処は別問題で、Studio を閉じても履歴から結果を取れる、という話は 別記事 にまとめています。

重いと分かったあとのつなぎ

目的 参照
退勤前に結果が出ない/画面を閉じたい Studioを閉じても履歴から結果を見る
結果を名前付きで残してあとから使う 結果をテーブルに残す
多段SQLを読みやすくする WITHで中間に名前を付ける
リファクタ前後の一致確認 ハッシュ比較

失敗例と回避策

  • 失敗: 初めて見る表では、前月1か月分でも重くなる可能性がある。
    回避: 実行前に表の特徴とドライランを見る。他テーブル比で極端なら定義を疑う
  • 失敗: 3か月がいっぺんは遅いから、1か月×3並列にする(非パーティションのまま)
    回避: 1本あたりのスキャン見込みを見てから決める。フルスキャン近いなら並列はスロットを食うだけ、になりやすい
  • 失敗: SQLの問題だけでなく、テーブルの設計にも注意が必要です。
    回避: パーティションとスキャン量を先に確認する

まとめ

  • 前月1か月なのに他テーブル比で極端に遅いときは、まず相手テーブル(巨大明細・非パーティション)を疑う
  • 初見・あまり使っていない表ほど、いつもの軽さの感覚が通じず気づきやすい
  • 直近3か月を1か月×3並列にすると、フルスキャン3本でスロットを圧迫しやすい
  • 実行前チェックは、パーティション有無と、前月1本分のスキャン見込み
  • 待ち方・残し方は、履歴確認や結果テーブル化の記事へつなぐ

次に読む

タイトルとURLをコピーしました