Максимальный размер запроса SQL Server? В статье? Есть ли лучший подход [дубликат]


Возможный дубликат:
T-SQL где col в (...)

Каков максимальный размер запроса SQL Server? (#символов)

Максимальный размер для предложения IN? Я думаю, что видел что-то о том, что у Oracle есть ограничение на 1000 элементов, но вы можете обойти это с помощью ANDing 2 INs вместе. Аналогичная проблема в SQL Server?

Обновление Итак, какой будет лучший подход, если мне нужно взять, скажем, 1000 GUID из другой системы (не реляционной базы данных) и "вступить в коде на SQL-сервере? Нужно ли подавать список из 1000 GUID в пункт IN? Или есть другая техника, которая работает более эффективно?

Я не проверял это, но мне интересно, могу ли я представить GUID в виде XML-документа. Например

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

А затем выполните какое-то соединение XQuery против Doc и таблицы. Менее эффективно, чем 1000 пунктов в предложении?

4 85

4 ответа:

Каждый пакет SQL должен соответствовать ограничению размера пакета : 65 536 * размер сетевого пакета.

Кроме этого, ваш запрос ограничен условиями выполнения. Обычно он исчерпывает размер стека, потому что x в (a, b, c) - это не что иное, как x=a или x=b или x=c, что создает дерево выражений, подобное x=a или (x=b или (x=c)), поэтому он становится очень глубоким с большим количеством OR. SQL 7 ударил бы SO примерно на 10k значений в IN , но теперь стеки гораздо глубже (из-за x64), так что она может идти довольно глубоко.

Обновить

Вы уже нашли статью Эрланда на тему передачи списков/массивов в 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;

Максимумы SQL Server раскрываются http://msdn.microsoft.com/en-us/library/ms143432.aspx (это версия 2008 года)

SQL-запрос может быть varchar (max), но отображается как ограниченный размером сетевого пакета 65 536*, но даже в этом случае наиболее вероятно, что вы ошибетесь, это 2100 параметров на запрос. Если SQL решит параметризовать литеральные значения в предложении in, я думаю, что вы сначала достигнете этого предела,но я не проверял его.

Edit: проверьте его, даже под принудительная параметризация это пережило - я стучал быстрый тест и имел его выполнение с 30K пунктов в пункте In. (SQL Server 2005)

В 100k пунктов, это заняло некоторое время, затем упал с:

Msg 8623, Уровень 16, Состояние 1, Строка 1 Обработчик запросов исчерпал внутренние ресурсы и не смог создать план запроса. Это редкое событие и ожидается только для чрезвычайно сложных запросов или запросов, ссылающихся на очень большое количество таблиц или разделов. Пожалуйста упростите запрос. Если вы считаете, что получили это сообщение по ошибке, обратитесь в Службу поддержки клиентов за дополнительной информацией.

Так что 30k можно, но только потому, что вы можете это сделать - не значит, что вы должны :)

Edit: Продолжение из-за дополнительного вопроса.

50k сработало, но 60k выпало, так что где-то там на моей испытательной установке кстати.

С точки зрения того, как сделать это объединение значений без использования большого предложения in, лично я бы создал temp таблица, вставьте значения в эту временную таблицу, проиндексируйте ее и затем используйте в соединении, предоставляя ему наилучшие возможности для оптимизации соединений. (Генерация индекса на временной таблице создаст для него статистику, которая, как правило, поможет оптимизатору, хотя 1000 GUID не будут точно считать статистику слишком полезной.)

На пакет, 65536 * размер сетевого пакета, который составляет 4k so 256 MB

Однако, в остановится путь до этого, но это не точно.

Вы заканчиваете с ошибками в памяти, но я не могу вспомнить точную ошибку. Огромный ин будет неэффективен в любом случае.

Edit: Remus напомнил мне: ошибка связана с "размером стека"

Можете ли вы загрузить GUID в таблицу scratch, а затем сделать

... WHERE var IN SELECT guid FROM #scratchtable