Максимальный размер для SQL Server Query? IN? Есть ли лучший подход?
Возможный дубликат:
T-SQL WHERE col IN (…)
Каков максимальный размер запроса SQL Server? (# символов)
Максимальный размер для предложения IN? Я думаю, что я видел что-то о том, что Oracle имеет ограничение на 1000 единиц, но вы можете обойти это вместе с ANDing 2 INs. Аналогичная проблема в SQL Server?
UPDATE
Итак, какой был бы наилучший подход, если мне нужно будет сказать 1000 GUID из другой системы (Non Relational Database) и сделать "JOIN in code" в отношении SQL Server? Представляет ли он список 1000 GUID для предложения IN?
Или есть другой метод, который работает более эффективно?
Я не тестировал это, но мне интересно, могу ли я представить GUID как XML-документ. Например
<guids>
<guid>809674df-1c22-46eb-bf9a-33dc78beb44a</guid>
<guid>257f537f-9c6b-4f14-a90c-ee613b4287f3</guid>
</guids>
а затем выполните какой-то XQuery JOIN против Doc и таблицы. Менее эффективен, чем 1000 item IN.
Ответы
Ответ 1
Каждая партия 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 примерно в 10 тыс. Значений в IN, но теперь стеки намного глубже (из-за x64), поэтому он может пойти довольно глубокий.
Обновление
Вы уже нашли статью Erland на тему передачи списков/массивов SQL Server. С 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;
Ответ 2
Максимальные значения SQL Server раскрываются http://msdn.microsoft.com/en-us/library/ms143432.aspx (это версия 2008 года)
SQL Query может быть varchar (max), но отображается как ограниченный размером 65536 * Network Packet, но даже тогда наиболее вероятным для вас является 2100 параметров для каждого запроса. Если SQL захочет параметризовать литеральные значения в предложении in, я бы подумал, что вы нажмете этот предел сначала, но я его не тестировал.
Изменить: протестировать его, даже при принудительной параметризации, он выжил - я опробовал быстрый тест и выполнил его с 30 тыс. элементов в разделе "В". (SQL Server 2005)
В пунктах 100 тыс. потребовалось некоторое время, а затем сброшено с помощью:
Msg 8623, уровень 16, состояние 1, строка 1 Обработчик запросов исчерпал внутренние ресурсы и не смог создать план запроса. Это редкое событие и ожидается только для чрезвычайно сложных запросов или запросов, которые ссылаются на очень большое количество таблиц или разделов. Пожалуйста, упростите запрос. Если вы считаете, что получили это сообщение по ошибке, обратитесь в Службу поддержки клиентов за дополнительной информацией.
Таким образом, возможно 30k, но только потому, что вы можете это сделать - не означает, что вы должны:)
Изменить: Продолжается из-за дополнительного вопроса.
50k сработало, но вышло 60 тысяч, поэтому где-то там на моей тестовой установке btw.
Что касается того, как сделать это объединение значений без использования большого предложения, лично я создам временную таблицу, вставляю значения в эту временную таблицу, индексирую ее, а затем использую в соединении, предоставляя ей лучшие возможности для оптимизации объединений. (Генерация индекса в таблице temp создаст для него статистику, что поможет оптимизатору в качестве общего правила, хотя 1000 GUID не будут точно находить статистику слишком полезной.)
Ответ 3
За пакет, 65536 * Размер сетевого пакета, который составляет 4k, поэтому 256 МБ
Однако IN остановится раньше, но не будет точным.
В результате возникают ошибки памяти, но я не могу вспомнить точную ошибку.
В любом случае, огромный IN будет неэффективным.
Изменить: Remus напомнил мне: ошибка касается размера стека
Ответ 4
Можете ли вы загрузить идентификаторы GUID в таблицу царапин, затем выполните
... WHERE var IN SELECT guid FROM #scratchtable