SQLチューニング

プログラミング

競馬予想プログラミングに関する記事を「投稿まとめ」で一覧にしてます。この記事は「自動投票」の一覧に含まれてます。一覧の順に読むとステップごとで分かりやすいです。

同じ要件を満たすSQLでも、作り方によって実行速度が大きく変わる場合があります。その処理が遅いと、

  • 自動投票で締切時間に間に合わない。
  • データ分析が楽しくない。

なんてことになりかねません。この章ではSQLやプロシージャの高速化、つまり「SQLチューニング」の基本的なテクニックを紹介します。

インデックスを作る

インデックスの作成が「SQLチューニング」において最もシンプルで効果的です。しかし、インデックスの仕組みを正しく理解してないと逆効果になる場合もあります。

インデックスに関する話は「インデックスを作成する(CREATE INDEX)」の記事を参考にしてください。ここから先は、インデックスを作る以外の「SQLチューニング」のテクニックを紹介します。

不要なORDER BY句は使わない

当たり前ですが、ORDER BY句には並べ替えの処理が発生します。処理には大小問わず時間が必要です。なので、その並べ替えは本当に必要か?よく考えてください。

例えば「INSERT〜SELECT」のSELECT文にORDER BY句は無意味です。登録するのに並び順なんか関係ないから。ORDER BY句にかぎった話ではなく、結果が同じなら不要です。

サブクエリの結果を一時的に保存

これは特にプロシージャで有効なテクニックになります。「サブクエリ」とはネスト(入れ子)したSELECT文。つまり、SELECT文の中にあるSELECT文です。

複雑なサブクエリが原因でSELECT文の実行に時間がかかる。その検索結果が大量にある。という場合は、いったんテーブルに登録するとトータルで高速になる可能性が高いです。

大きな仕事をまとめてやるより、少しずつに分類したほうが速い、ということが人間の世界でもあります。また、複雑になりがちなサブクエリを使うSQLを整理しやすく、可読性も高まります。具体的な流れは、

  1. サブクエリの結果を保存するテーブルを用意する。これを「一時表」と呼ぶことにします。
  2. DELETE→INSERTの流れでサブクエリの結果を一時表に登録。
  3. 一時表をメインのSQLの、FROM句かJOIN句で使う。

ただし状況によってサブクエリのままのほうが高速な場合もあるので、どちらがベストな選択か実際に実行しながら比較してください。

範囲検索は「BETWEEN」を使う

これは劇的な効果を感じませんが、理論的に速くなります。SQLチューニングを極めたい人は使ってください。

遅い→2つの演算子で範囲検索

WHERE
kaisai_nen >= '2021' AND
kaisai_nen <= '2022'

速い→「BETWEEN」で範囲検索

WHERE
kaisai_nen BETWEEN '2021' AND '2022'

人間が見れば明らかに同じ要求ですがプログラムは書いたとおりに実行します。「BETWEEN」で速くなる理由は「BETWEEN」の場合、項目(※ここでは kaisai_nen)の参照が1回だけなので、インデックスを見る回数も2回から1回に減るからです。

でも私は「BETWEEN」は使ってません。その理由は「BETWEEN」は範囲検索でしか使えないけど、演算子はいずれか片方でも書き方が同じ。演算子の書き方は見た目に一貫性があり、grepやファイル検索のとき便利だからです。

まとめ

要するにSQLチューニングは、

  1. インデックスを有効に使う。
  2. 無駄な処理でリソースを無駄遣いしない。
  3. データベースの読み書き回数を減らす。

にかかってます。テクニックはここに書いた以外にもまだまだありますが、全て紹介すると難しく感じてしまうので、競馬予想プログラミングに使えそうなモノだけ書きました。もっと知りたい方は「SQLチューニング」でググってください。また、どんな小さいことでも、

  • この変数は本当に必要か?
  • プログラムの行数をもっと少なく出来ないか?
  • この処理はもっと高速化できないか?

と考えながら書くのを習慣にすることで品質の高いプログラムを書けるようになります。

「投稿まとめ」にもどる