Sql-Server
CTE 執行多少次
如果我有如下程式碼之類的 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 ;