Сведения о вопросе

profi

16:03, 1st July, 2020

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

Просмотров: 473   Ответов: 8

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

-- SQL Server 2000

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

-- SQL Server 2005

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

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

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


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

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

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



  Сведения об ответе

VCe znayu

18:03, 1st July, 2020

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

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

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

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

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

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


  Сведения об ответе

COOL

18:03, 1st July, 2020

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

Ваш первый вопрос должен быть, вероятно, следующим: "Почему так много?", за которым следует "what bits of information do I NOT need?", я бы беспокоился, что количество данных, возвращаемых из такого запроса, также начнет довольно сильно влиять на производительность приложения.


  Сведения об ответе

screen

18:03, 1st July, 2020

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


  Сведения об ответе

SEEYOU

18:03, 1st July, 2020

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

Решение, как говорит Дилли-о, состоит в том, чтобы определить соответствующие "sub-joins" (предпочтительно те, которые используются несколько раз) и разложить их на переменные временной таблицы, которые затем используются в ваших основных соединениях. Это основной PIA и часто убивает производительность. Мне очень жаль тебя.

@Kevin, люблю эту футболку -- говорит все :-).


  Сведения об ответе

DAAA

18:03, 1st July, 2020

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

Довольно глупо считать, что логическое исполнение то же самое...


  Сведения об ответе

davran

18:03, 1st July, 2020

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


  Сведения об ответе

screen

18:03, 1st July, 2020

Разместить запрос :D

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


  Сведения об ответе

pumpa

18:03, 1st July, 2020

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться