Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】A SQL Heuristic: ORs Are Expensive

2025年09月29日に「Hacker News」が公開したITニュース「A SQL Heuristic: ORs Are Expensive」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

SQL文で複数の条件を「OR」で結合すると、データベースの処理コストが高くなり、データ検索のパフォーマンスが低下しやすい。システムエンジニアはSQL設計時、OR句の使用には注意し、より効率的なクエリの書き方を検討する必要がある。

出典: A SQL Heuristic: ORs Are Expensive | Hacker News公開日:

ITニュース解説

データベースは、システムが大量のデータを効率的に管理し、必要な情報を素早く取り出すための重要な基盤である。そのデータを操作するために使われるのがSQLという言語だ。システムエンジニアにとって、SQLを使ってデータベースから効率良くデータを取得する能力は不可欠だ。特に、クエリのパフォーマンスはシステム全体の応答速度に直結するため、非常に重要なテーマとなる。

SQLクエリの中でも、特定の条件を満たすデータを絞り込む際にWHERE句を使用する。複数の条件のうち、いずれか一つでも満たせば良いという場合によく使われるのがOR句である。例えば、「Aさんのデータ、またはBさんのデータ」といった形で、複数の選択肢の中から該当するものを探し出す際に便利に見える。しかし、このOR句の利用方法によっては、データベースのパフォーマンスが著しく低下する可能性があるという経験則が知られている。

データベースのパフォーマンスを語る上で欠かせないのが「インデックス」の概念だ。インデックスは、書籍の索引のようなもので、特定のデータがどこに格納されているかを素早く見つけるための仕組みである。インデックスが適切に設定されていれば、データベースは必要なデータに直接アクセスでき、大量のデータを一つ一つ調べ上げる「フルスキャン」を避けることができる。これは、広大な情報の中から目的の情報を見つける際に、目次や索引を使うことで効率化するのと同様の原理である。

OR句がパフォーマンスを低下させる主な原因は、このインデックスの利用を阻害することが多い点にある。データベースは、SQLクエリが実行された際に、そのクエリをどのように実行すれば最も効率的かを判断する「クエリオプティマイザ」という機能を持っている。しかし、OR句が含まれる場合、オプティマイザは最適な実行計画を立てるのが難しいことがある。 例えば、「カラムA = 値X または カラムB = 値Y」というOR条件を考える。もしカラムAカラムBそれぞれにインデックスが設定されていても、データベースはカラムA = 値Xに該当する行と、カラムB = 値Yに該当する行の両方を探し出し、それらを結合する必要がある。このとき、インデックスを別々に利用して結果セットを作成し、その二つの結果セットをマージする処理は、単一のインデックスを使って一つの条件を満たす行を探すよりもはるかに複雑で時間がかかる場合が多い。 特に、OR句で参照するカラムが異なる場合や、参照するカラムにインデックスが設定されていない場合は、結局データベースはテーブル全体をスキャンせざるを得なくなり、結果としてパフォーマンスが大幅に低下してしまう。これは、二つの異なる情報源から情報を収集し、かつその結果を統合する作業の煩雑さに近い。

このようなOR句のパフォーマンス問題を回避するための有効な手段の一つが、UNION ALLを使用することである。UNION ALLは、複数のSELECT文の結果を結合するためのSQLキーワードだ。例えば、「カラムA = 値X または カラムB = 値Y」というOR条件を、「SELECT ... WHERE カラムA = 値X」というクエリと、「SELECT ... WHERE カラムB = 値Y」というクエリに分割し、これらをUNION ALLで結合する。 この方法の利点は、各SELECT文が独立して処理されるため、それぞれのクエリが自身のWHERE句の条件に基づいて効率的にインデックスを利用できる点にある。つまり、データベースは「カラムA = 値X」の条件でカラムAのインデックスを使って結果セットを生成し、「SELECT ... WHERE カラムB = 値Y」の条件でカラムBのインデックスを使って結果セットを生成する。その後、これらの結果セットを単純に結合する。このアプローチは、複雑なマージ処理を減らし、インデックスの効果を最大限に引き出すため、OR句を使った場合よりも高速になることが多い。

また、OR句の中でも特定のパターン、例えば「カラムA = 値X または カラムA = 値Y または カラムA = 値Z」のように、同じカラムに対して複数の等価条件を指定する場合には、IN句を利用する方が望ましい。IN句は「カラムA IN (値X, 値Y, 値Z)」のように記述でき、多くの場合、データベースのオプティマイザはこれを効率的に処理し、インデックスを適切に利用する実行計画を生成できる。これはOR句が抱えるパフォーマンス問題とは性質が異なり、多くの場合ORより推奨される。

OR句が常にパフォーマンスの悪化を招くわけではない。非常に小規模なデータセットに対して実行される場合や、特定のデータベースシステムやバージョンにおけるオプティマイザの進化によっては、OR句でも効率的な実行計画が生成されることもある。しかし、特に大規模なデータベースや、将来的にデータ量が増加する可能性のあるシステムを設計・開発する際には、OR句の使用には慎重になるべきだという経験則は非常に重要である。 システムエンジニアとして、SQLクエリのパフォーマンスを意識することは、システムの安定性やユーザー体験に直結する。OR句がボトルネックとなる可能性を理解し、必要に応じてUNION ALLIN句といった代替手段を検討することは、より効率的で堅牢なシステムを構築するための基本的なスキルとなるだろう。データベースの特性を理解し、クエリの意図を正確に伝えつつ、パフォーマンスを最大化する書き方を常に模索することが、優れたシステムエンジニアへの道なのだ。

関連コンテンツ