101

重複の可能性:
T-SQL WHERE col IN(…)

SQL Serverクエリの最大サイズはいくつですか?(文字数)

IN句の最大サイズ?Oracleには1000アイテムの制限があることを知ったと思いますが、2つのINをANDで結合することでこれを回避できます。SQL Serverの同様の問題?

更新 では、別のシステム(非リレーショナルデータベース)から1000個のGUIDを取得し、SQL Serverに対して「コードで結合」する必要がある場合の最善のアプローチは何でしょうか?1000個のGUIDのリストをIN句に送信することですか? ?または、より効率的に機能する別の手法はありますか?

これはテストしていませんが、GUIDをXMLドキュメントとして送信できるかどうか疑問に思います。例えば

<guids>
    <guid>809674df-1c22-46eb-bf9a-33dc78beb44a</guid>
    <guid>257f537f-9c6b-4f14-a90c-ee613b4287f3</guid>
</guids>

次に、ドキュメントとテーブルに対して何らかのXQueryJOINを実行します。1000アイテムのIN句よりも効率が悪いですか?

4

4 に答える 4

86

すべての SQL バッチは、バッチ サイズ制限: 65,536 * ネットワーク パケット サイズに収まる必要があります。

それ以外は、クエリは実行時の条件によって制限されます。x IN (a,b,c) は x=a OR (x=b OR (x =c))なので、多数のORで非常に深くなります。SQL 7 はIN の約 10k の値で SO にヒットしますが、現在のスタックは (x64 のため) はるかに深いため、かなり深くなる可能性があります。

アップデート

リスト/配列を SQL Server に渡すトピックに関する Erland の記事を既に見つけました。SQL 2008 では、DataTable 全体を単一のテーブル タイプ パラメータとして渡して結合できるテーブル値パラメータもあります

XML と XPath も実行可能なソリューションです。

SELECT ...
FROM Table
JOIN (
   SELECT x.value(N'.',N'uniqueidentifier') as guid
   FROM @values.nodes(N'/guids/guid') t(x)) as guids
 ON Table.guid = guids.guid;
于 2009-12-08T21:01:47.620 に答える
41

SQL Server の最大数はhttp://msdn.microsoft.com/en-us/library/ms143432.aspxで公開されています(これは 2008 バージョンです) 。

SQL クエリは varchar(max) にすることができますが、65,536 * ネットワーク パケット サイズに制限されているように示されていますが、それでもつまずく可能性が最も高いのは、クエリごとに 2100 個のパラメーターです。SQL が in 句でリテラル値をパラメーター化することを選択した場合、最初にその制限に達すると思いますが、テストしていません。

編集:それをテストしてください。強制的なパラメーター化の下でも生き残りました-簡単なテストを行い、In句内の30kアイテムで実行しました。(SQL サーバー 2005)

100,000 個のアイテムで、しばらく時間がかかり、次のように削除されました。

メッセージ 8623、レベル 16、状態 1、行 1 クエリ プロセッサが内部リソースを使い果たし、クエリ プランを作成できませんでした。これはまれなイベントであり、非常に複雑なクエリ、または非常に多数のテーブルまたはパーティションを参照するクエリでのみ予想されます。クエリを簡略化してください。このメッセージを誤って受け取ったと思われる場合は、詳細についてカスタマー サポート サービスにお問い合わせください。

したがって、30kは可能ですが、それができるからといって、そうすべきだという意味ではありません:)

編集:追加の質問により続行。

50k は機能しましたが、60k はドロップアウトしたため、テスト リグのどこかにありました。

大きな in 句を使用せずに値の結合を行う方法に関しては、個人的には一時テーブルを作成し、その一時テーブルに値を挿入し、インデックスを作成してから結合で使用し、最適な機会を与えます結合を最適化します。(一時テーブルにインデックスを生成すると、その統計が作成されます。これは、一般的なルールとしてオプティマイザーに役立ちますが、GUID が 1000 の場合、統計が有用すぎるとは限りません。)

于 2009-12-08T20:58:34.647 に答える
14

バッチあたり、65536 *ネットワークパケットサイズは4k、つまり256 MB

ただし、INはその前に停止しますが、正確ではありません。

メモリーエラーが発生しますが、正確なエラーを思い出せません。とにかく巨大なINは非効率的です。

編集:Remusは私に思い出させました:エラーは「スタックサイズ」に関するものです

于 2009-12-08T20:56:46.450 に答える
8

GUIDをスクラッチテーブルにロードしてから、

... WHERE var IN SELECT guid FROM #scratchtable
于 2009-12-08T21:14:20.340 に答える