La dimensione massima per un server di query SQL? IN clausola? C'è un approccio migliore [duplicato]

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

  •  18-09-2019
  •  | 
  •  

Domanda

  

Eventuali duplicati:
   T-SQL WHERE col IN (...)

Qual è la dimensione massima per una query SQL Server? (# Di caratteri)

Dimensione massima per una proposizione IN? Credo di aver visto qualcosa su Oracle avere un limite di 1000 articolo, ma si potrebbe aggirare il problema con AND 2 INs insieme. problema simile in SQL Server?

Aggiorna Quindi, quale sarebbe l'approccio migliore se ho bisogno di prendere dire 1000 GUID da un altro sistema (database non relazionali) e fare un "JOIN in codice' contro lo SQL Server? E' a presentare l'elenco dei 1000 GUID di una clausola IN? O c'è un'altra tecnica che funziona in modo più efficiente?

Non ho ancora testato questo, ma mi chiedo se ho potuto presentare i GUID come un doc XML. Ad esempio

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

e poi fare una sorta di XQuery JOIN contro il Doc e la Tavola. Meno efficiente di 1000 articolo clausola?

È stato utile?

Soluzione

Ogni lotto SQL deve adattarsi nel Batch Size Limit : 65.536 * Packet Network Dimensioni.

Oltre a questo, la query è limitata dalle condizioni di esecuzione. Sarà normalmente eseguito stack perché x IN (a, b, c) non è altro che x = a O x = b OR x = c che crea un albero di espressione simile a x = a O (x = b OR (x = c)), quindi diventa molto profondo con un gran numero di OR. SQL 7 avrebbe colpito un rel="noreferrer"> href="http://support.microsoft.com/kb/288095" SO , ma oggigiorno le pile sono molto più profondo ( a causa del x64), in modo che possa andare abbastanza in profondità.

Aggiorna

È già trovato l'articolo di Erland sul tema del passaggio liste / matrici a SQL Server. Con SQL 2008 hai anche tabella dei parametri stimati che consentono di passare un intero DataTable come un singolo parametro di tipo tavolo e aderire su di esso.

XML e XPath è un'altra soluzione possibile:

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;

Altri suggerimenti

i massimi di SQL Server sono divulgati http://msdn.microsoft.com/ it-it / library / ms143432.aspx (questa è la versione 2008)

Una query SQL può essere un varchar (max), ma è indicato come limitata a 65.536 size * Network Packet, ma anche allora ciò che è più probabile che viaggio fino sono i parametri 2100 per query. Se SQL sceglie di parametrizzare i valori letterali nella clausola, penserei che ci ha colpito tale limite prima, ma ho havn't testato.

Modifica: Provarlo, anche sotto parameteriztion forzata è sopravvissuto - ho messo incinta un test rapido e avuto esecuzione con 30k elementi all'interno della clausola. (SQL Server 2005)

A 100k articoli, ci volle del tempo poi è sceso con:

  

Messaggio 8623, livello 16, stato 1, riga 1   Il processore di query ha esaurito le risorse interne e non potrebbe produrre un piano di query. Questo è un evento raro e previsto solo per le interrogazioni estremamente complesse o query che fanno riferimento a un gran numero di tabelle o partizioni. Semplificare la query. Se ritieni di aver ricevuto questo messaggio per errore, contattare il Servizio di assistenza clienti per ulteriori informazioni.

Quindi 30k è possibile, ma solo perché si può fare - non significa che si dovrebbe:)

Modifica:. Continua a causa di domanda aggiuntiva

50k ha funzionato, ma 60k abbandonato, quindi da qualche parte in là sul mio banco di prova btw.

In termini di come farlo unire dei valori senza l'utilizzo di una grande nella clausola, personalmente vorrei creare una tabella temporanea, inserire i valori in quella tabella temporanea, indicizzarlo e poi usarlo in un join, dandogli la migliori opportunità di optimse join. (Generazione l'indice sulla tabella temporanea creerà statistiche per esso, che aiuterà l'ottimizzatore come regola generale, anche se 1000 GUID non sarà esattamente trovare statistiche troppo utile.)

per partita, 65536 * Network Packet Size che è 4k così 256 MB

Tuttavia, in modo si fermerà prima di quella, ma non è preciso.

Si finisce con gli errori di memoria, ma non riesco a ricordare l'errore esatto. Un enorme IN sarà inefficiente in ogni caso.

Modifica: Remo mi ha ricordato: l'errore è di circa "stack"

Si può caricare i GUID in una tabella zero poi fare un

... WHERE var IN SELECT guid FROM #scratchtable
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top