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

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

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

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

обновление Так что было бы лучшим подходом, если мне нужно взять, скажем, 1000 GUID из другой системы (не реляционной базы данных) и сделать "присоединиться к коду" против SQL Server? Это представить список 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 ответов


каждый пакет 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, я бы подумал, что вы сначала достигнете этого предела, но я его не тестировал.

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

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

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

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

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

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

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


в пакете 65536 * Размер Сетевого Пакета который 4k так 256 MB

однако, in остановится до этого, но это не точно.

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

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


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

... WHERE var IN SELECT guid FROM #scratchtable