Я недавно сталкивался с этой проблемой и не мог найти никакого обсуждения этого онлайн.
Запрос ниже
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;
В чем причина такого поведения? и есть ли лучший обходной путь, чем тот, который я нашел? (что, возможно, не требует дополнительных ветвей плана выполнения)