web-dev-qa-db-ja.com

SQLのwhere句の順序は重要ですか?

3つの列ID, LastName, FirstNameを持つPEOPLEというテーブルがあるとします。これらの列はどれもインデックス付けされていません。
LastNameはより一意であり、FirstNameは一意ではありません。

2回検索した場合:

select * from PEOPLE where FirstName="F" and LastName="L" 
select * from PEOPLE where LastName="L" and FirstName="F"

LastName句でより一意な基準(where)が最初に来て、レコードがより効率的に削除されるため、私の信念は2番目に速いです。オプティマイザーが最初のsqlを最適化するほど賢いとは思わない。

私の理解は正しいですか?

106
Ziyang Zhang

いいえ、その順序は重要ではありません(少なくとも、重要ではありません)。

適切なクエリオプティマイザーは、allWHERE句の部分を見て、そのクエリを満たす最も効率的な方法を見つけ出します。

SQL Serverクエリオプティマイザーが適切なインデックスを選択することはわかっています-2つの条件がどの順序にある​​かに関係なく、他のRDBMSにも同様の戦略があると思います。

重要なのは、これに適したインデックスがあるかどうかです!

SQL Serverの場合、次の場合にインデックスを使用する可能性があります。

  • (LastName, FirstName)のインデックス
  • (FirstName, LastName)のインデックス
  • (LastName)のみ、または(FirstName)のみ(または両方)のインデックス

一方、SQL Serverの場合-SELECT *を使用してテーブルからall列を取得し、テーブルがかなり小さい場合は、クエリオプティマイザーが単にインデックスを使用する代わりにテーブル(またはクラスター化インデックス)スキャンを実行します(フルデータページへのルックアップによりall他の列が非常に高速になりすぎるため)。

85
marc_s

WHERE句の順序は、SQL標準に準拠するデータベースで違いを生じないようにする必要があります。評価の順序は、ほとんどのデータベースで保証されていません。

SQLが順序を気にしているとは思わないでください。以下は、SQL Serverでエラーを生成します。

select *
from INFORMATION_SCHEMA.TABLES
where ISNUMERIC(table_name) = 1 and CAST(table_name as int) <> 0

この句の最初の部分が最初に実行された場合、数値のテーブル名のみが整数としてキャストされます。ただし、失敗し、SQL Serverは(他のデータベースと同様に)WHEREステートメントの句の順序を気にしないという明確な例を提供します。

15
Gordon Linoff

ANSI SQL Draft 2003 5WD-01-Framework-2003-09.pdf

6.3.3.3ルール評価の順序

...

優先順位が形式または括弧によって決定されない場合、式の効果的な評価は一般に左から右に実行されます。ただし、特にオペランドまたは演算子が条件を発生させる可能性がある場合、または式のすべての部分を完全に評価せずに式の結果を決定できる場合、式が実際に左から右に評価されるかどうかは実装に依存します。

here からコピー

9
03Usr

いいえ、すべてのRDBMは最初にクエリを分析して開始し、where句を並べ替えて最適化します。

使用しているRDBMに応じて、分析の結果を表示できます(たとえば、OracleでExplain Planを検索します)

M.

2
poussma

元のOPステートメント

私の信念は、よりユニークな基準(LastName)がwhere節で最初に来るため、2番目の方が速くなり、レコードがより効率的に削除されることです。オプティマイザーが最初のsqlを最適化するほど十分に賢いとは思わない。

インデックスの作成中に列の順序を選択することとこれを混同していると思います。2番目に選択的な列よりも選択的な列を最初に配置する必要があります。

ところで、上記の2つのクエリでは、SQLサーバーオプティマイザーは最適化を行いませんが、プランの総コストが並列処理しきい値コスト未満である限り、Trivilaプランを使用します。

1
Gulli Meel

名前にインデックスが付けられていないと仮定すると、それは事実です。ただし、データが異なるとエラーになります。毎回異なる可能性のある方法を見つけるために、DBMSは各列に対して個別のカウントクエリを実行し、数値を比較する必要があります。

0
Tony Hopkinson