Проблема
При заполнении переменной таблицы множеством строк, а затем ее объединении с другими таблицами оптимизатор запросов может выбрать неэффективный план запросов, что может замедлить выполнение запросов.
Решение
После применения этого исправления можно включить флаг трассировки 2453, чтобы переменная таблицы запускала перекомпиляцию при изменении достаточного числа строк. Это может позволить оптимизатору запросов выбрать более эффективный план.
Эта проблема была впервые исправлена в следующем накопительном пакете обновления или пакете обновления для SQL Server.
Накопительный пакет обновления 3 для SQL Server 2014 г. /en-us/help/2984923
Сведения о накопительных обновлениях для SQL Server
Каждый новый накопительный пакет обновления для SQL Server содержит все исправления и исправления безопасности, которые входили в состав предыдущего накопительного пакета обновления. Ознакомьтесь с последними накопительными пакетами обновления для SQL Server:
Пакет обновления 2 для SQL Server 2012
Сведения о пакетах обновления для SQL Server
Пакеты обновления суммируются. Каждый новый пакет обновления содержит все исправления, которые были в предыдущих пакетах обновления, а также все новые исправления. Мы рекомендуем применять последний пакет обновления и последний накопительный пакет обновления для этого пакета обновления. Перед установкой последнего пакета обновления устанавливать предыдущий пакет обновления не требуется. Дополнительные сведения о последнем пакете обновления и последнем накопительном пакете обновления см. в таблице 1 в следующей статье:
Определение версии, выпуска и уровня обновления SQL Server и его компонентов
Дополнительные сведения
При использовании табличной переменной в пакете или процедуре запрос компилируется и оптимизируется для начального пустого состояния табличной переменной. Если эта табличная переменная заполняется множеством строк во время выполнения, предварительно скомпилированный план запроса может быть неоптимальным. Например, запрос может соединять переменную таблицы с вложенным циклом, так как это обычно более эффективно для небольшого количества строк. Этот план запроса может быть неэффективным, если переменная таблицы содержит миллионы строк. В таких условиях хэш-соединение может быть лучшим выбором. Чтобы получить новый план запросов, его необходимо скомпилировать заново. Однако, в отличие от других пользовательских или временных таблиц, изменение количества строк в переменной таблицы не приводит к перекомпиляции запроса. Как правило, эту проблему можно обойти с помощью функции OPTION (RECOMPILE), которая имеет свои собственные накладные расходы.
Флаг трассировки 2453 позволяет выполнять перекомпиляцию запроса без OPTION (RECOMPILE). Этот флаг трассировки отличается от OPTION (RECOMPILE) двумя основными аспектами.
(1) В ней используется то же пороговое значение количества строк, что и в других таблицах. Запрос не нужно компилировать для каждого выполнения, в отличие от OPTION (RECOMPILE). Она запускает перекомпиляцию только в том случае, если изменение количества строк превышает предопределенный порог.
(2) OPTION (RECOMPILE) заставляет запрос просматривать параметры и оптимизировать запрос для них. Этот флаг трассировки не приводит к принудительному просмотру параметра.
Обратите внимание, что этот флаг трассировки должен быть включен во время выполнения. Этот флаг трассировки нельзя использовать с функцией QUERYTRACEON. Этот флаг трассировки следует использовать с осторожностью, так как он может увеличить количество перекомпиляций запросов, что может стоить больше, чем экономия за счет лучшей оптимизации запросов.
Состояние
Корпорация Майкрософт подтвердила, что это проблема продуктов Microsoft, перечисленных в разделе «Относится к».