SQL Server中的臨時表和表變量有什麼區別?

在SQL Server 2005中,咱們可使用如下兩種方式之一建立臨時表: 數據庫

declare @tmp table (Col1 int, Col2 int);

要麼 服務器

create table #tmp (Col1 int, Col2 int);

二者之間有什麼區別? 對於@tmp是否仍使用tempdb或內存中是否發生了全部事情,我有不一樣意見。 網絡

在哪種狀況下賽過另外一種? session


#1樓

  1. 臨時表:臨時表易於建立和備份數據。 函數

    表變量:可是,當咱們一般建立普通表時,表變量會涉及工做量。 性能

  2. 臨時表:臨時表結果可由多個用戶使用。 測試

    表變量:可是表變量只能由當前用戶使用。 優化

  3. 臨時表:臨時表將存儲在tempdb中。 它將產生網絡流量。 當臨時表中有大量數據時,它就必須跨數據庫工做。 將存在性能問題。 spa

    表變量:可是表變量將在物理內存中存儲一​​些數據,而後在大小增長時將其移到tempdb。 code

  4. 臨時表:臨時表能夠執行全部DDL操做。 它容許建立索引,刪除,更改等。

    表變量:表變量不容許執行DDL操做。 可是table變量只容許咱們建立聚簇索引。

  5. 臨時表:臨時表可用於當前會話或全局會話。 這樣,多用戶會話就能夠利用表中的結果。

    表變量:可是表變量能夠在該程序中使用。 (存儲過程)

  6. 臨時表:臨時變量不能使用事務。 當咱們使用臨時表進行DML操做時,它能夠回滾或提交事務。

    表變量:可是咱們不能對錶變量執行此操做。

  7. 臨時表:函數不能使用臨時變量。 此外,咱們沒法在函數中執行DML操做。

    表變量:可是該函數容許咱們使用表變量。 可是使用表變量,咱們能夠作到這一點。

  8. 臨時表:當咱們爲每一個後續調用使用temp變量時,存儲過程將進行從新編譯(不能使用相同的執行計劃)。

    表變量:表變量不會那樣作。


#2樓

@wcm-其實是要選擇表變量,而不只僅是Ram-它能夠部分存儲在磁盤上。

臨時表能夠具備索引,而表變量只能具備主索引。 若是速度是一個問題,表變量可能會更快,可是很顯然,若是有不少記錄,或者須要搜索彙集索引的臨時表,那麼臨時表會更好。

好背景文章


#3樓

對於全部相信temp變量僅在內存中的神話的人

首先,表變量不必定是駐留內存的。 在內存壓力下,能夠將屬於表變量的頁面推出到tempdb。

在這裏閱讀文章: TempDB ::表變量與本地臨時表


#4樓

在哪種狀況下賽過另外一種?

對於較小的表(少於1000行),請使用臨時變量,不然請使用臨時表。


#5樓

引用來自; 專業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 ;

使用哪個?

是否使用臨時表或表變量應該經過全面的測試來肯定,可是最好將臨時 表做爲默認表,由於 出錯的地方 要少得多

我已經看到客戶使用表變量開發代碼,由於他們處理的是少許的行,而且比臨時表要快,可是幾年後,表變量中有成千上萬的行,而且性能不好,所以請在作出決定時嘗試進行一些容量規劃!

相關文章
相關標籤/搜索