2011-08-09 33 views
4

我們的客戶的數據庫管理員都要求我們不使用臨時表我們的報告存儲過程(#Table)內,而是利用表變量。SQL服務器臨時表VS表變量

是表變量比臨時表的效率低?

另外,如果我創建一個表爲#table,而不是##table,一個一個#是一個會話表,而不是在##這是全球性的,對不對?當stored procedure完成,並且你沒有做DROP TABLE #table ... #table仍然存在?如果它是基於會話的,那麼我會再次訪問它嗎?

+2

注意:表變量沒有統計信息,也不參與事務處理。需要牢記的事情。 –

+0

很多人都誤以爲表變量總是在內存中,而臨時表則在tempdb中並打到磁盤上。這兩個都不是嚴格正確的(它們實際上都在tempdb中,如果可能的話,它們都會留在內存中,如果需要,它們都會溢出到磁盤) –

+0

可能重複[SQL Server中臨時表和表變量之間的區別?] (http://stackoverflow.com/questions/27894/whats-the-difference-between-a-temp-table-and-table-variable-in-sql-server) – Makoto

回答

2

表變量會導致比臨時表更少的存儲過程重新編譯(請參閱知識庫文章#243586和知識庫文章#305977),並且 - 由於無法回滾它們,因此不必打擾事務日誌。

##table是belogs到全局臨時表。 yes #table不存在,因爲它僅在給定範圍內,並且您從不訪問它。

編輯

我也喜歡點利用CTE(公共表表達式),因爲它在某種程度上也作爲工作的臨時表。 檢查這個答案詳細:Which are more performant, CTE or temporary tables?

+0

鑑於問題「是#table不存在因爲它只在給定的範圍內,而且你永遠不會在特定範圍內訪問它「這是誤導性的。 #table存在於會話範圍內。因此,您可以從同一個會話中調用的另一個存儲過程再次訪問它。這意味着它在清理之前必須比表變量更長。 –

0

我不是100%肯定你問什麼,因爲你的標題中提到的表變量,你被要求使用表變量,但你的問題問一無所知表變量。 ..但是表變量的聲明一樣:

DECLARE @Banana TABLE 
(
    Id INT, 
    Name VARCHAR(20) 
) 
-1

如果本地臨時表(#table)在創建SP,SP結束後它會被丟棄。 BOL說:

  • 在存儲過程中創建的本地臨時表時自動下降 :當他們走出去的範圍, 除非使用DROP TABLE顯式刪除

    臨時表自動刪除存儲過程完成。該表可以是 ,由創建該表的存儲的 過程執行的任何嵌套存儲過程引用。該表不能被 調用創建該表的存儲過程的過程引用。

  • 所有其它本地臨時表在當前會話的 結束時自動刪除。

  • 當創建該表的會話 結束並且所有其他任務已停止 引用它們時,將自動刪除全局臨時表。一個任務和一個表之間的關聯是 ,僅在單個Transact-SQL語句的生命週期中維護。這 意味着全局臨時表是在 最後的Transact-SQL語句積極引用 表當創建活動結束後完成下降。