Чому посилання на змінну в приєднувальній силі вкладених циклів?


16

Я нещодавно зіткнувся з цим питанням і не зміг знайти жодного обговорення цього питання в Інтернеті.

Запит нижче

DECLARE @S VARCHAR(1) = '';

WITH T
     AS (SELECT name + @S AS name2,
                *
         FROM   master..spt_values)
SELECT *
FROM   T T1
       INNER JOIN T T2
         ON T1.name2 = T2.name2;

Завжди отримує вкладений план циклів

введіть тут опис зображення

Спроба змусити проблему за допомогою INNER HASH JOINабо INNER MERGE JOINпідказки призводить до наступної помилки.

Процесор запиту не зміг скласти план запиту через підказки, визначені в цьому запиті. Повторно надішліть запит, не вказуючи жодних підказок і не використовуючи SET FORCEPLAN.

Я знайшов вирішення, яке дозволяє використовувати хеш або злиття приєднання - загортання змінної в сукупність. Генерований план значно нижчий затрати (19.2025 проти 0.261987)

DECLARE @S2 VARCHAR(1) = '';

WITH T
     AS (SELECT name + (SELECT MAX(@S2)) AS name2,
                *
         FROM   spt_values)
SELECT *
FROM   T T1
       INNER JOIN T T2
         ON T1.name2 = T2.name2; 

введіть тут опис зображення

У чому причина такої поведінки? і чи є кращий шлях, ніж той, який я знайшов? (що, можливо, не вимагає додаткових гілок плану виконання)

Відповіді:


13

Я спробував ваш запит на екземплярі SQL 2012 і прапор трасування 4199, здається, вирішив проблему. Якщо це ввімкнено, я отримую об'єднання об'єднань загальною вартістю 0,24 та жодну із зайвих гілок.

Конкретна стаття KB для цього випуску - Проблеми з продуктивністю виникають, коли предикат об’єднання у вашому запиті має стовпці зовнішніх посилань у SQL Server 2005 або в SQL Server 2008

введіть тут опис зображення

Для подальшої кваліфікації TF 4199 дає можливість виправити всі оптимізатори. Для отримання додаткової інформації див. Це посилання . Увімкнення всього одразу може мати дивні побічні ефекти, тому, якщо ви зможете знайти конкретне виправлення, можливо, краще включити виправлення самостійно.

Ви можете ввімкнути прапор трассингу на основі запиту, використовуючи OPTION (QUERYTRACEON 4199);


0

Старе запитання, але побачивши відповідь не було надто остаточним, подумав, що опублікую знайдене нами вирішення. Не впевнений, чому запит оптимізатора запитує HASH, але я думаю, що це не подобається, MERGEоскільки він не має впорядкованого введення. 2012/14 р.

DECLARE @S VARCHAR(1) = '';

    WITH T
        AS (SELECT TOP (2147483647)
                name + @S AS name2,
                *
            FROM   master..spt_values
            ORDER BY name + @S)
    SELECT *
    FROM   T T1
           INNER JOIN T T2
             ON T1.name2 = T2.name2;

складається наступний план:

введіть тут опис зображення

Здається, форсування TOPта ORDER BYcte, схоже, дають оптимізатору достатньо знань про набір даних для виконання MERGE JOIN.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.