Sql-Server

CTE 執行多少次

  • February 9, 2022

如果我有如下程式碼之類的 cte。表 People 被查詢了多少次?我的印像是它只被呼叫了 1 次並儲存在記憶體中,但我一直在執行的一些查詢似乎比它們應該執行的時間長得多。這讓我相信它可能會擊中 People Table 3 次。

with ctegeneric as (select person from people where person = 'dumb')
Select * from ctegeneric 
UNION ALL
Select * from ctegeneric 
UNION ALL
Select * from ctegeneric 

撇開語法不正確(在編輯之前)。

不,它不會被放入記憶體中。

一個合適的例子是連接。它將在循環連接中多次呼叫。在一個昂貴的 CTE 上呼叫多次然後實現到 #temp 是要走的路。

在 SQL 中,CTE 只能在定義它的(一個)語句中使用/引用。我們通過使用語句終止符 ( ;) 知道語句在哪裡結束。

SQL Server 是寬容的,並允許開發人員不要放置這些終止符(除了它確實抱怨的特殊情況),但在每條語句之後使用它們確實是一種很好的做法(微軟推薦它)。如果您放置它們,很明顯您的程式碼將解析為 3 個語句:

--- 1st statement starts ---
with ctegeneric as (select person from people where person = 'dumb') 
Select * from ctegeneric ;    -- and ends here

--- 2nd statement starts ---
Select * from ctegeneric ;    -- and ends here

--- 3rd statement starts ---
Select * from ctegeneric ;    -- and ends here

所以你的第二個和第三個語句實際上根本不應該工作,並且會返回錯誤:

INVALID OBJECT NAME: ctegeneric

一旦創建 CTE 的語句結束,您就無法再次引用它。

有點像(這也不是有效的語法,只是考慮 CTE 的另一種方式):

WITH ctegeneric AS (SELECT person 
                   FROM people 
                   WHERE person = 'dumb')

BEGIN
Select * from ctegeneric ;
END

但是,您可以使用以下命令執行三個選擇UNION/UNION ALL

WITH ctegeneric AS (SELECT person 
                   FROM people 
                   WHERE person = 'dumb')   
Select * from ctegeneric
UNION
Select * from ctegeneric
UNION
Select * from ctegeneric ;

引用自:https://dba.stackexchange.com/questions/150207