SQLを作る際に、要件や用途が同じでも、SQLを分けた方が良いケースがあることを学んだので備忘録として書いておきます。(仕事で書くドキュメントっぽくなってしまいました)
発端
ある SELECT 文のパフォーマンスが悪く、他のSQLと比べて実行時間が非常に長いという問題が発生しました。調査したところ、SQL内で大量のレコードを JOIN していることが原因でした。
問題の背景
このSQLは、ユーザーのサービスの契約状態を見て、それに適合したレコードを表示するという要件を満たすためのものでした。
しかし、対象となるサービスの中には、大量のレコードを見なければならないものが含まれていました。
改善案
問題のサービスは、ごく一部のユーザー(全体の約1%)しか契約しないものだったため、以下のような対応を行うことにしました
• SQLを発行する前に、サービスの契約状態を条件分岐で判定する。
• 条件分岐の結果に応じて、異なるSQLを発行するように変更する。
なぜこの対応が有効か?
• 大多数のユーザー(約99%)に対して無駄な JOIN を行わなくて済む。
• 大多数のユーザーにとっての処理が効率化されることで、全体的なパフォーマンスが向上。
実施結果
問題となっていた JOIN や WHERE 句を減らしたSQLを別に作成したところ、
パフォーマンスが大幅に改善されました。めでたしめでたし。
まとめ
サービスの契約状況が特定のユーザーに偏っている場合、
SQLを一つにまとめるのではなく、状況に応じてSQLを分けるアプローチが有効であると学びました。