sql >> Base de Datos >  >> RDS >> Sqlserver

¿La instrucción WITH se ejecuta una vez por consulta o una vez por fila?

Ejemplo:

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;

Si ejecuta el script anterior en SSMS (presione Ctrl+M -> Plan de ejecución real), obtendrá este plan de ejecución para la última consulta:

En este caso, el CTE se ejecuta una vez para crt alias y cinco (!) veces para prev alias, una vez por cada fila de crt .

Entonces, la respuesta para esta pregunta

es both :una vez por consulta (crt ) y una vez por fila (prev :una vez por cada desde crt ).

Para optimizar esta consulta, para empezar, 1) Puede intentar almacenar los resultados de CTE (MyCTE o Query ) en una variable de tabla o una tabla temporal

2) Defina la clave principal de esta tabla como la(s) columna(s) de unión,

3) Vuelva a escribir la consulta final para usar esta variable de tabla o tabla temporal.

Por supuesto, puede intentar reescribir la consulta final sin esta unión automática entre CTE.