Maximale Größe für eine SQL Server -Abfrage? In Klausel? Gibt es einen besseren Ansatz [Duplikat

StackOverflow https://stackoverflow.com/questions/1869753

  •  18-09-2019
  •  | 
  •  

Frage

Mögliches Duplikat:
T-sql wo col in (…)

Was ist die maximale Größe für eine SQL -Server -Abfrage? (Anzahl der Zeichen)

Maximale Größe für eine In -Klausel? Ich glaube, ich habe etwas über Oracle gesehen, das ein 1000 -Punkte -Limit hat, aber Sie könnten dies mit und 2 -Ins -Zusammenarbeit umgehen. Ähnliches Problem in SQL Server?

AKTUALISIERENWas wäre also der beste Ansatz, wenn ich 1000 Guids aus einem anderen System (nicht relationale Datenbank) sagen und einen "Code -Code" gegen den SQL -Server durchführen muss? Ist es, die Liste von 1000 Richtlinien an eine In -Klausel zu übermitteln? Oder gibt es eine andere Technik, die effizienter funktioniert?

Ich habe das nicht getestet, aber ich frage mich, ob ich die Richtlinien als XML -Dokument einreichen könnte. Zum Beispiel

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

Und dann schließen Sie sich eine Art XQuery gegen den Dokument und den Tisch an. Weniger effizient als 1000 Artikel in Klausel?

War es hilfreich?

Lösung

Jede SQL -Stapel muss in die passen Batchgrößengrenze: 65.536 * Netzwerkpaketgröße.

Ansonsten ist Ihre Abfrage durch Laufzeitbedingungen begrenzt. Normalerweise geht es aus der Stapelgröße aus, weil x in (a, b, c) nichts anderes ist als x = a oder x = b oder x = c, was einen Ausdrucksbaum erstellt, der ähnlich wie x = a oder (x = b oder (x) ähnelt = c)), also wird es mit einer großen Anzahl von OR sehr tief. SQL 7 würde eine SO treffen bei ca. 10k Werten in der in, Aber heutzutage sind Stapel viel tiefer (wegen x64), so dass es ziemlich tief werden kann.

Aktualisieren

Sie haben den Artikel von Erland bereits zum Thema Übergabe von Listen/Arrays an SQL Server gefunden. Mit SQL 2008 haben Sie auch Tabelle wertvolle Parameter Auf diese Weise können Sie einen gesamten DataTable als einzelner Tabellentypparameter übergeben und sich daran anschließen.

XML und XPath sind eine weitere praktikable Lösung:

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;

Andere Tipps

Die Maximums von SQL Server werden offengelegt http://msdn.microsoft.com/en-us/library/ms143432.aspx (Dies ist die Version 2008)

Eine SQL -Abfrage kann ein Varchar (max) sein, ist jedoch als begrenzt auf 65.536 * Netzwerkpaketgröße angezeigt, aber selbst dann sind Sie die 2100 Parameter pro Abfrage am wahrscheinlichsten. Wenn sich SQL dafür entscheidet, die wörtlichen Werte in der In -Klausel zu parametrisieren, würde ich denken, Sie würden diese Grenze zuerst treffen, aber ich habe es nicht getestet.

Bearbeiten: Testen Sie es, selbst unter erzwungener Parameterizität überlebte es - ich habe einen kurzen Test geschlagen und es mit 30.000 Elementen innerhalb der In -Klausel ausführen lassen. (SQL Server 2005)

Bei 100.000 Artikeln dauerte es einige Zeit und fiel mit:

MSG 8623, Stufe 16, Status 1, Zeile 1 Der Abfrageprozessor hat die internen Ressourcen mehr als einen Abfrageplan erstellen. Dies ist ein seltenes Ereignis, das nur für extrem komplexe Abfragen oder Abfragen erwartet wird, die auf eine sehr große Anzahl von Tabellen oder Partitionen hinweisen. Bitte vereinfachen Sie die Abfrage. Wenn Sie der Meinung sind, dass Sie diese Nachricht fehlerhaft erhalten haben, wenden Sie sich an Customer Support -Dienste, um weitere Informationen zu erhalten.

Also ist 30k möglich, aber nur weil du es schaffen kannst - heißt das nicht, dass du es solltest :)

Bearbeiten: Fortsetzung aufgrund zusätzlicher Frage.

50k funktionierten, aber 60k brachen aus, also irgendwo in meinem Test -Rig übrigens.

In Bezug darauf, wie diese Verbindung der Werte ohne Verwendung einer großen Klausel verwendet werden kann, würde ich persönlich eine Temp -Tabelle erstellen, die Werte in diese Temp -Tabelle einfügen, sie indexieren und dann in einem Join verwenden, um die besten Möglichkeiten dazu zu geben Optimse die Anschlüsse. (Generieren des Index in der TEMP -Tabelle erstellen Statistiken dafür, was dem Optimierer in der Regel hilft, obwohl 1000 Guids nicht genau Statistiken zu nützlich finden.)

Pro Charge, 65536 * Netzwerkpaketgröße Das ist 4k so 256 MB

Im Voraus hört es jedoch weit davon an, aber es ist nicht präzise.

Sie haben Speicherfehler, aber ich kann mich nicht an den genauen Fehler erinnern. Ein großes in wird sowieso ineffizient sein.

Bearbeiten: Remus erinnerte mich: Der Fehler geht über "Stapelgröße"

Können Sie die Guids in eine Kratzentabelle laden und dann a machen

... WHERE var IN SELECT guid FROM #scratchtable
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top