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

Возможный дубликат:
T-SQL ГДЕ col IN (…)

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

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

ОБНОВЛЕНИЕ Итак, что будет лучшим подходом, если мне нужно взять, скажем, 1000 GUID из другой системы (не реляционная база данных) и выполнить "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 против Дока и Таблицы. Менее эффективно, чем 1000 пунктов в предложении?

4 ответа

Решение

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

Обновить

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

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

На 100 тыс. Предметов это заняло некоторое время, а затем упало с:

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

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

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

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

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

За пакет, 65536 * Размер сетевого пакета, который составляет 4 КБ, 256 МБ

Однако IN остановится намного раньше, но это не точно.

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

Редактировать: Ремус напомнил мне: ошибка о "размере стека"

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

... WHERE var IN SELECT guid FROM #scratchtable
Другие вопросы по тегам