Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

A instrução WITH é executada uma vez por consulta ou uma vez por linha?


Exemplo:
SET NOCOUNT ON;
SET IMPLICIT_TRANSACTIONS ON;

CREATE TABLE MyTable (MyID INT  PRIMARY KEY);
GO
INSERT  MyTable (MyID)
VALUES  (11), (22), (33), (44), (55);

PRINT 'Test MyCTE:';
WITH MyCTE
AS (
    SELECT  *, ROW_NUMBER()OVER(ORDER BY MyID) AS RowNum
    FROM    MyTable
)
SELECT  *
FROM    MyCTE crt
LEFT JOIN MyCTE prev ON crt.RowNum=prev.RowNum+1;

ROLLBACK;

Se você executar o script anterior no SSMS (pressione Ctrl+M -> Plano de Execução Real) então você obterá este plano de execução para a última consulta:

Neste caso, o CTE é executado uma vez para crt alias e cinco (!) vezes para prev alias, uma vez para cada linha de crt .

Então, a resposta para esta pergunta

é both :uma vez por consulta (crt ) e uma vez por linha (prev :uma vez para cada para de crt ).

Para otimizar esta consulta, para começar,1) Você pode tentar armazenar os resultados do CTE (MyCTE ou Query ) em uma variável de tabela ou em uma tabela temporária

2) Defina a chave primária desta tabela como sendo a(s) coluna(s) de junção,

3) Reescreva a consulta final para usar essa variável de tabela ou tabela temporária.

Claro, você pode tentar reescrever a consulta final sem essa autojunção entre CTE.