在SQL Server 2005中,咱們可使用如下兩種方式之一建立臨時表: 數據庫
declare @tmp table (Col1 int, Col2 int);
要麼 服務器
create table #tmp (Col1 int, Col2 int);
二者之間有什麼區別? 對於@tmp是否仍使用tempdb或內存中是否發生了全部事情,我有不一樣意見。 網絡
在哪種狀況下賽過另外一種? session
臨時表:臨時表易於建立和備份數據。 函數
表變量:可是,當咱們一般建立普通表時,表變量會涉及工做量。 性能
臨時表:臨時表結果可由多個用戶使用。 測試
表變量:可是表變量只能由當前用戶使用。 優化
臨時表:臨時表將存儲在tempdb中。 它將產生網絡流量。 當臨時表中有大量數據時,它就必須跨數據庫工做。 將存在性能問題。 spa
表變量:可是表變量將在物理內存中存儲一些數據,而後在大小增長時將其移到tempdb。 code
臨時表:臨時表能夠執行全部DDL操做。 它容許建立索引,刪除,更改等。
表變量:表變量不容許執行DDL操做。 可是table變量只容許咱們建立聚簇索引。
臨時表:臨時表可用於當前會話或全局會話。 這樣,多用戶會話就能夠利用表中的結果。
表變量:可是表變量能夠在該程序中使用。 (存儲過程)
臨時表:臨時變量不能使用事務。 當咱們使用臨時表進行DML操做時,它能夠回滾或提交事務。
表變量:可是咱們不能對錶變量執行此操做。
臨時表:函數不能使用臨時變量。 此外,咱們沒法在函數中執行DML操做。
表變量:可是該函數容許咱們使用表變量。 可是使用表變量,咱們能夠作到這一點。
臨時表:當咱們爲每一個後續調用使用temp變量時,存儲過程將進行從新編譯(不能使用相同的執行計劃)。
表變量:表變量不會那樣作。
@wcm-其實是要選擇表變量,而不只僅是Ram-它能夠部分存儲在磁盤上。
臨時表能夠具備索引,而表變量只能具備主索引。 若是速度是一個問題,表變量可能會更快,可是很顯然,若是有不少記錄,或者須要搜索彙集索引的臨時表,那麼臨時表會更好。
對於全部相信temp變量僅在內存中的神話的人
首先,表變量不必定是駐留內存的。 在內存壓力下,能夠將屬於表變量的頁面推出到tempdb。
在這裏閱讀文章: TempDB ::表變量與本地臨時表
在哪種狀況下賽過另外一種?
對於較小的表(少於1000行),請使用臨時變量,不然請使用臨時表。
引用來自; 專業SQL Server 2012內部和故障排除
統計信息臨時表和表變量之間的主要區別在於,不會在表變量上建立統計信息。 這有兩個主要結果,首先是查詢優化器對錶變量中的行數使用固定估計,而不考慮其包含的數據。 此外,添加或刪除數據不會改變估計值。
索引儘管能夠建立約束,但沒法在表變量上建立索引。 這意味着經過建立主鍵或惟一約束,您能夠在表變量上具備索引(由於建立這些索引是爲了支持約束)。 即便您有約束,所以索引也將具備統計信息,可是在編譯查詢時將不使用索引,由於它們在編譯時將不存在,也不會致使從新編譯。
模式修改能夠在臨時表上進行模式修改,但不能在表變量上進行模式修改。 儘管能夠在臨時表上進行模式修改,可是請避免使用它們,由於它們會致使從新編譯使用該表的語句。
表變量未在內存中建立
常見的誤解是表變量是內存結構,所以其執行速度要比臨時錶快 。 多虧了一個名爲sys的DMV。 dm _ db _ session _ space _ usage,按會話顯示tempdb的使用狀況, 您能夠證實並不是如此 。 從新啓動SQL Server清除DMV後,運行如下腳原本確認您的會話_ id爲用戶_對象_分配_頁面_ count返回0:
SELECT session_id, database_id, user_objects_alloc_page_count FROM sys.dm_db_session_space_usage WHERE session_id > 50 ;
如今,您能夠經過運行如下腳原本建立臨時表,並用一行填充並填充一行,以檢查臨時表使用了多少空間:
CREATE TABLE #TempTable ( ID INT ) ; INSERT INTO #TempTable ( ID ) VALUES ( 1 ) ; GO SELECT session_id, database_id, user_objects_alloc_page_count FROM sys.dm_db_session_space_usage WHERE session_id > 50 ;
我服務器上的結果代表該表在tempdb中分配了一頁。 如今運行相同的腳本,可是此次使用表變量:
DECLARE @TempTable TABLE ( ID INT ) ; INSERT INTO @TempTable ( ID ) VALUES ( 1 ) ; GO SELECT session_id, database_id, user_objects_alloc_page_count FROM sys.dm_db_session_space_usage WHERE session_id > 50 ;
使用哪個?
是否使用臨時表或表變量應該經過全面的測試來肯定,可是最好將臨時 表做爲默認表,由於 出錯的地方 要少得多 。
我已經看到客戶使用表變量開發代碼,由於他們處理的是少許的行,而且比臨時表要快,可是幾年後,表變量中有成千上萬的行,而且性能不好,所以請在作出決定時嘗試進行一些容量規劃!