Depende.
Em primeiro lugar
O que é uma expressão de tabela comum?
Uma CTE (não recursiva) é tratada de maneira muito semelhante a outras construções que também podem ser usadas como expressões de tabela embutidas no SQL Server. Tabelas derivadas, exibições e funções com valor de tabela embutida. Observe que, embora BOL diga que um CTE "pode ser considerado um conjunto de resultados temporário", esta é uma descrição puramente lógica. Na maioria das vezes, não é materializado por direito próprio.
O que é uma tabela temporária?
Esta é uma coleção de linhas armazenadas em páginas de dados em tempdb. As páginas de dados podem residir parcial ou totalmente na memória. Além disso, a tabela temporária pode ser indexada e ter estatísticas de coluna.
Dados de teste
CREATE TABLE T(A INT IDENTITY PRIMARY KEY, B INT , F CHAR(8000) NULL);
INSERT INTO T(B)
SELECT TOP (1000000) 0 + CAST(NEWID() AS BINARY(4))
FROM master..spt_values v1,
master..spt_values v2;
Exemplo 1
WITH CTE1 AS
(
SELECT A,
ABS(B) AS Abs_B,
F
FROM T
)
SELECT *
FROM CTE1
WHERE A = 780
Observe que no plano acima não há menção ao CTE1. Ele apenas acessa as tabelas base diretamente e é tratado da mesma forma que
SELECT A,
ABS(B) AS Abs_B,
F
FROM T
WHERE A = 780
Reescrever materializando o CTE em uma tabela temporária intermediária aqui seria extremamente contraproducente.
Materializando a definição do CTE de
SELECT A,
ABS(B) AS Abs_B,
F
FROM T
Envolveria copiar cerca de 8 GB de dados em uma tabela temporária, então ainda haveria a sobrecarga de selecionar também.
Exemplo 2
WITH CTE2
AS (SELECT *,
ROW_NUMBER() OVER (ORDER BY A) AS RN
FROM T
WHERE B % 100000 = 0)
SELECT *
FROM CTE2 T1
CROSS APPLY (SELECT TOP (1) *
FROM CTE2 T2
WHERE T2.A > T1.A
ORDER BY T2.A) CA
O exemplo acima leva cerca de 4 minutos na minha máquina.
Apenas 15 linhas dos 1.000.000 de valores gerados aleatoriamente correspondem ao predicado, mas a varredura de tabela cara acontece 16 vezes para localizá-los.
Este seria um bom candidato para materializar o resultado intermediário. A reescrita da tabela temporária equivalente levou 25 segundos.
INSERT INTO #T
SELECT *,
ROW_NUMBER() OVER (ORDER BY A) AS RN
FROM T
WHERE B % 100000 = 0
SELECT *
FROM #T T1
CROSS APPLY (SELECT TOP (1) *
FROM #T T2
WHERE T2.A > T1.A
ORDER BY T2.A) CA
A materialização intermediária de parte de uma consulta em uma tabela temporária às vezes pode ser útil mesmo que seja avaliada apenas uma vez - quando permite que o restante da consulta seja recompilado aproveitando as estatísticas sobre o resultado materializado. Um exemplo dessa abordagem está no artigo SQL Cat When To Break Down Complex Queries.
Em algumas circunstâncias, o SQL Server usará um spool para armazenar em cache um resultado intermediário, por exemplo, de um CTE, e evite ter que reavaliar aquela subárvore. Isso é discutido no item Connect (migrado) Fornecer uma dica para forçar a materialização intermediária de CTEs ou tabelas derivadas. No entanto, nenhuma estatística é criada sobre isso e mesmo que o número de linhas em spool fosse muito diferente do estimado, não é possível que o plano de execução em andamento se adapte dinamicamente em resposta (pelo menos nas versões atuais. Planos de consulta adaptáveis podem se tornar possíveis em o futuro).