1. ホーム
  2. sql

[解決済み] SQL IN はパフォーマンスに影響するのか?

2023-06-15 13:39:41

質問

次のようなクエリがあります。

SELECT FieldX, FieldY FROM A
WHERE FieldW IN (108, 109, 113, 138, 146, 160,
307, 314, 370, 371, 441, 454 ,457, 458, 479, 480,
485, 488, 490, 492, 519, 523, 525, 534, 539, 543,
546, 547, 550, 564, 573, 629, 642, 643, 649, 650,
651, 694, 698, 699, 761, 762, 768, 772, 773, 774,
775, 778, 784, 843, 844, 848, 851, 852, 853, 854,
855, 856, 857, 858, 859, 860, 861, 862, 863, 864,
865, 868, 869, 871, 872, 873, 891) 

IN句に多くのオプションがあると、クエリのパフォーマンスに悪影響があるのでしょうか?私のアプリケーションでは多くのタイムアウトが発生しており、この種の問題の原因である可能性があると思います。何か良い SQL ヒントを使用して、数字を削除せずにクエリを最適化することは可能ですか?

EDITです。

@KM これらは別のテーブルのキーです。これはフォーラム アプリケーションで、簡単に説明すると、C# はデータベースからすべてのフォーラムを取得し、アプリ キャッシュに保存します。C# はこれらのフォーラムとこのユーザーのスレッドを取得するプロシージャを呼び出す前に、C# は "all forums" コレクションをフィルタリングし、権限といくつかのビジネス ロジックを考慮するいくつかのロジックを実行します。タイムアウトは、アプリケーション自体ではなく、データベース上で発生します。クエリでこのロジックをすべて実行するには、多くの内部結合が必要で、プロシージャ内でこれをすべて実行できるかどうか100%確信が持てません。

私は SQL Server 2000

どのように解決するのですか?

IN 演算子を使用してクエリを記述する場合、パフォーマンスに影響を与えるいくつかの考慮事項があります。

まず、IN 節は一般に、ほとんどのデータベースで OR 論理接続を使用するように内部的に書き換えられます。 そこで col IN ('a','b','c') は次のように書き換えられます。 (COL = 'a') OR (COL = 'b') or (COL = 'c') . 両方のクエリの実行計画は 可能性が高い にインデックスがあると仮定すると、両者の実行計画は同等になります。 col .

次に、IN または OR を可変数の引数で使用する場合、引数が変わるたびにデータベースがクエリを再解析し、実行計画を再構築しなければならない原因となっています。 クエリの実行計画を構築することは、高価なステップとなり得ます。ほとんどのデータベースは、実行されたクエリの実行計画を、EXACTクエリテキストをキーとしてキャッシュしています。もし、同じようなクエリを実行しても、述語の引数の値が違えば、データベースの解析と実行計画の構築に多大な時間を費やすことになります。このため バインド変数が強く推奨される理由です。 を強く推奨する理由です。

第三に、多くのデータベースは、実行できるクエリの複雑さに制限を持っています。それらの制限の1つは、述語に含めることができる論理接続詞の数です。 あなたの場合、数十個の値はデータベースの組み込み制限に達することはないでしょうが、もしあなたがIN句に数百または数千の値を渡すことを期待しているなら、それは間違いなく起こり得ます。この場合、データベースは単にクエリ要求をキャンセルします。

第四に、述語に IN と OR を含むクエリは、常に並列環境で最適に書き直すことはできません。 並列サーバの最適化が適用されないケースはいろいろあるんですよー。 MSDNに適切な紹介があります。 を参照してください。しかし一般的に、UNION ALL 演算子を使用するクエリは、ほとんどのデータベースで自明な並列化が可能であり、可能であれば (OR や IN など) 論理接続詞よりも好ましいとされています。