Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Изявлението WITH изпълнява ли се веднъж на заявка или веднъж на ред?

Пример:

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;

Ако стартирате предишен скрипт в SSMS (натиснете Ctrl+M -> Действителен план за изпълнение), тогава ще получите този план за изпълнение за последната заявка:

В този случай CTE се изпълнява еднократно за crt псевдоним и пет (!) пъти за prev псевдоним, веднъж за всеки ред от crt .

И така, отговорът на този въпрос

е both :веднъж на заявка (crt ) и веднъж на ред (prev :веднъж за всеки за от crt ).

За да оптимизирате тази заявка, като начало,1) Можете да опитате да съхраните резултатите от CTE (MyCTE или Query ) в променлива на таблица или временна таблица

2) Дефинирайте първичния ключ на тази таблица като колона(и) за присъединяване,

3) Пренапишете последната заявка, за да използвате тази променлива на таблицата или временна таблица.

Разбира се, можете да опитате да пренапишете крайната заявка без това самостоятелно свързване между CTE.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Грешка в операционната система на SQL Server 5:5 (Достъпът е отказан.)

  2. Вземете ден от седмицата в SQL Server 2005/2008

  3. Как да използвате семантично търсене в SQL Server

  4. Закръглете милисекунди на .NET DateTime, за да може да побере милисекунди на SQL Server

  5. Има ли начин за показване на резултати от PRINT с JDBC драйвер на SQL сървър?