Вы когда-нибудь встречали запрос, который SQL Server не мог выполнить, потому что он ссылался на слишком много таблиц? - PullRequest
16 голосов
/ 05 августа 2008

Вы когда-нибудь видели какие-либо сообщения об ошибках?

- SQL Server 2000

Не удалось выделить вспомогательную таблицу для разрешения представления или функции.
Превышено максимальное количество таблиц в запросе (256).

- SQL Server 2005

Слишком много имен таблиц в запросе. Максимально допустимое значение составляет 256.

Если да, что ты сделал?

Отказался? Убедить клиента упростить его требования? Денормализовать базу данных?


@ (все хотят, чтобы я отправил запрос):

  1. Я не уверен, смогу ли я вставить 70 килобайт кода в окно редактирования ответа.
  2. Даже если я смогу, это не поможет, поскольку эти 70 килобайт кода будут ссылаться на 20 или 30 просмотров, которые мне также придется публиковать, так как иначе код будет бессмысленным.

Я не хочу звучать так, как будто хвастаюсь здесь, но проблема не в запросах. Запросы являются оптимальными (или, по крайней мере, почти оптимальными). Я провел бесчисленные часы, оптимизируя их, просматривая каждый столбец и каждую отдельную таблицу, которую можно удалить. Представьте себе отчет, содержащий 200 или 300 столбцов, который должен быть заполнен одним оператором SELECT (потому что он был разработан несколько лет назад, когда он был еще небольшим отчетом).

Ответы [ 8 ]

8 голосов
/ 05 августа 2008

Для SQL Server 2005 я бы порекомендовал использовать табличные переменные и частично строить данные по мере необходимости.

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

Затем найдите вашу основную таблицу (скажем, таблицу заказов в приведенном выше примере) и извлеките эти данные, а также немного дополнительных данных, например, одно соединение (имя клиента, название продукта). Вы можете сделать SELECT INTO, чтобы поместить это прямо в переменную таблицы.

Оттуда итерируйте таблицу и для каждой строки выполните несколько небольших запросов SELECT, которые извлекают все дополнительные данные, необходимые для набора результатов. Вставьте их в каждый столбец по ходу дела.

После завершения вы можете сделать простой SELECT * из вашей табличной переменной и вернуть этот набор результатов пользователю.

У меня нет для этого точных чисел, но я до сих пор работал над тремя отдельными случаями, когда выполнение этих небольших запросов фактически работало быстрее, чем выполнение одного массивного запроса select с кучей объединений. 1011 *

1 голос
/ 02 ноября 2008

Это может происходить все время при написании отчетов служб Reporting Services для установок Dynamics CRM, работающих на SQL Server 2000. CRM имеет хорошо нормализованную схему данных, что приводит к множеству объединений. На самом деле есть исправление, которое увеличит предел с 256 до колоссальных 260: http://support.microsoft.com/kb/818406 (мы всегда думали, что это отличная шутка со стороны команды SQL Server).

Решение, на которое ссылается Дилли-О, состоит в том, чтобы идентифицировать соответствующие «подсоединения» (предпочтительно те, которые используются несколько раз) и выделить их в переменные временной таблицы, которые вы затем используете в своих основных объединениях. Это крупная PIA и часто убивает производительность. Я извиняюсь за тебя.

@ Кевин, люби эту футболку - все сказано: -).

1 голос
/ 05 августа 2008

@ chopeen Вы можете изменить способ расчета этих статистических данных и вместо этого вести отдельную таблицу со всеми статистическими данными по каждому продукту. При размещении заказа циклически просматривайте продукты и обновляйте соответствующие записи в таблице статистики , Это переместит большую часть расчетной нагрузки на страницу оформления заказа, вместо того, чтобы выполнять все в одном большом запросе при запуске отчета. Конечно, есть некоторые статистические данные, которые не будут работать таким образом, например, отслеживание следующих покупок клиентов после покупки определенного товара.

1 голос
/ 05 августа 2008

Я никогда не сталкивался с подобной ситуацией, и, честно говоря, идея сослаться на> 256 таблиц в запросе вызывает у меня смертельный страх.

Ваш первый вопрос, вероятно, должен звучать так: «Почему так много?», За которым следует «какие биты информации мне НЕ нужны?» Я был бы обеспокоен тем, что объем данных, возвращаемых по такому запросу, также может сильно повлиять на производительность приложения.

0 голосов
/ 07 марта 2012

У меня была такая же проблема в SQL Server 2005 (работала в 2008 году), когда я хотел создать представление. Я решил проблему, создав хранимую процедуру вместо представления.

0 голосов
/ 19 августа 2010

У меня была такая же проблема ... мой ящик для разработки работает с SQL Server 2008 (представление работало нормально), но на производстве (с SQL Server 2005) представление не выполнялось. В итоге я создал представления, чтобы избежать этого ограничения, используя новые представления как часть запроса в представлении, которое выдало ошибку.

Глупо, учитывая логическое выполнение, то же самое ...

0 голосов
/ 05 августа 2008

Опубликовать запрос: D

Также я чувствую, что одной из возможных проблем может быть тонна (читай 200+) таблиц имен / значений, которые могут быть сведены в одну справочную таблицу.

0 голосов
/ 05 августа 2008

Мне бы хотелось увидеть этот запрос, но я представляю, что это какая-то проблема с каким-то итератором, и хотя я не могу придумать какие-либо ситуации, когда это возможно, я держу пари, что это из-за плохого while / case / cursor или тонна плохо реализованных представлений.

...