[解決済み] SQL IN はパフォーマンスに影響するのか?
質問
次のようなクエリがあります。
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 など) 論理接続詞よりも好ましいとされています。
関連
-
[解決済み] SQL ServerでSELECTからUPDATEする方法とは?
-
[解決済み] PHPでSQLインジェクションを防ぐにはどうしたらいいですか?
-
[解決済み] MySQLでコマンドラインを使用してSQLファイルをインポートするにはどうすればよいですか?
-
[解決済み] SQLテーブルで重複する値を検索する
-
[解決済み] SQL Server で複数行のテキストを 1 つのテキスト文字列に連結する方法
-
[解決済み] SQL Server の DateTime データ型から日付だけを返す方法
-
[解決済み] SQLのSELECTでIF...THENを実行するにはどうすればよいですか?
-
[解決済み] SQL Server にテーブルが存在するかどうかを確認する
-
[解決済み】SQL Serverで既存のテーブルにデフォルト値を持つカラムを追加する
-
[解決済み] SQL ServerでINNER JOINを使用して削除するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
解決策:java.sql.SQLException: ユーザー ''@'localhost'' (パスワード: YES を使用) のアクセスが拒否されました。
-
[解決済み] Oracle Trigger ORA-04098: トリガーが無効で、再バリデーションに失敗しました。
-
[解決済み] 1つのPostgreSQLクエリで複数のWITHステートメントを使用するには?
-
[解決済み] SQLサーバーでNULL = NULLがfalseに評価される理由
-
[解決済み] SQL Serverでシングルクォートをエスケープするにはどうすればよいですか?
-
[解決済み] SQL Serverで、指定したテーブルを参照しているすべての外部キーを一覧表示するにはどうすればよいですか?
-
[解決済み] NOT IN vs NOT EXISTS
-
[解決済み] Count()で条件を指定することは可能ですか?
-
[解決済み] SQL ServerでGROUP BYを使って文字列を連結する方法とは?
-
[解決済み] Entity Framework VS LINQ to SQL VS ADO.NETでストアドプロシージャを使う?[クローズド]