sql >> Databáze >  >> RDS >> Sqlserver

Provede se příkaz WITH jednou na dotaz nebo jednou na řádek?

Příklad:

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;

Pokud spustíte předchozí skript v SSMS (stiskněte Ctrl+M -> Skutečný plán provádění), pak získáte tento plán provádění pro poslední dotaz:

V tomto případě se CTE provede jednou pro crt alias a pět (!) krát pro prev alias, jednou pro každý řádek z crt .

Takže odpověď na tuto otázku

je both :jednou na dotaz (crt ) a jednou na řádek (prev :jednou za každý z crt ).

Chcete-li tento dotaz optimalizovat, pro začátek,1) Můžete zkusit uložit výsledky z CTE (MyCTE nebo Query ) do proměnné tabulky nebo dočasné tabulky

2) Definujte primární klíč této tabulky jako sloupec(y) spojení

3) Přepište poslední dotaz tak, aby používal tuto proměnnou tabulky nebo dočasnou tabulku.

Samozřejmě se můžete pokusit přepsat konečný dotaz bez tohoto vlastního spojení mezi CTE.




  1. Jak vytvořit tabulku v SQL – Příklad dotazu Postgres a MySQL

  2. Nelze otevřít JPA EntityManager pro transakci; vnořená výjimka je javax.persistence.PersistenceException

  3. Proč CTE (Common Table Expressions) v některých případech zpomaluje dotazy ve srovnání s dočasnými tabulkami na SQL Server

  4. Jak mohu získat vzdálenost mezi dvěma body na Zemi z PostGIS?