Максимальный размер запроса 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