Me deparei com esse problema recentemente e não consegui encontrar nenhuma discussão on-line.
A consulta abaixo
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;
Sempre obtém um plano de loops aninhados
Tentar forçar o problema INNER HASH JOIN
ou INNER MERGE JOIN
dicas produz o seguinte erro.
O processador de consultas não pôde produzir um plano de consulta devido às dicas definidas nesta consulta. Submeta novamente a consulta sem especificar nenhuma dica e sem usar SET FORCEPLAN.
Eu encontrei uma solução alternativa que permite que junções de hash ou mesclagem sejam usadas - envolvendo a variável em um agregado. O plano gerado tem custo significativamente menor (19.2025 vs 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;
Qual o motivo desse comportamento? e existe uma solução melhor do que a que encontrei? (que talvez não exija as ramificações extras do plano de execução)