web-dev-qa-db-ja.com

SQL Serverクエリの最大サイズは? IN句?より良いアプローチはありますか

可能性のある複製:
T-SQL WHERE col IN(…)

SQL Serverクエリの最大サイズは? (文字数)

IN句の最大サイズ?私はオラクルが1000アイテムの制限を持っていることを見たと思いますが、2つのINをANDすることでこれを回避することができます。 SQL Serverでも同様の問題がありますか?

UPDATEしたがって、別のシステム(Non Relational Database)から1000 GUIDを取得して「JOIN inコード」をSQL Serverに対して実行しますか?1000のGUIDのリストをIN句に送信するのですか?それとも、より効率的に機能する別の手法がありますか?

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

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

次に、DocおよびTableに対して何らかのXQuery JOINを実行します。 1000アイテムのIN句よりも効率が悪いですか?

87
BuddyJoe

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

それ以外は、クエリは実行時の条件によって制限されます。 x IN(a、b、c)はx = a OR x = b OR x = cにすぎず、同様の式ツリーを作成するため、通常はスタックサイズを使い果たします。 x = a OR(x = b OR(x = c))であるため、多数のORを使用すると非常に深くなります。 SQL 7はSO INで約1万個の値で にヒットしますが、現在のスタックは(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;
73
Remus Rusanu

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

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

編集:強制的なparameteriztionの下でもテストし、生き残りました-クイックテストをノックアップし、In句内の3万アイテムで実行しました。 (SQL Server 2005)

10万個のアイテムでは、少し時間がかかり、次のようにドロップされました。

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

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

編集:追加の質問のために続きました。

50kは機能しましたが、60kはドロップアウトしたので、私のテスト装置のどこかにあるのです。

大きなin句を使用せずに値の結合を行う方法については、個人的に一時テーブルを作成し、その一時テーブルに値を挿入し、インデックスを作成してから結合で使用します。結合を最適化します。 (一時テーブルでインデックスを生成すると、そのための統計が作成されます。これは、一般的なルールとしてオプティマイザーを支援しますが、1000 GUIDでは正確に統計が有用ではありません。)

36
Andrew

バッチごと、 65536 *ネットワークパケットサイズ これは4kなので256 MB

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

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

編集:レムスは私に思い出させた:エラーは「スタックサイズ」についてです

12
gbn

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

... WHERE var IN SELECT guid FROM #scratchtable
7
DaveE