(轉)create table #temptable 臨時表 和 declare @bianliang table ()表變量


在開發過程中,經常會遇到使用表變量和本地臨時表的情況。下面是對二者的一個介紹:

1. 為什么要使用表變量

表變量是從2000開始引入的,微軟認為與本地臨時表相比,表變量具有如下優點:
  a.與其他變量的定義一樣,表變量具有良好的定義范圍,並會被自動清除;
  b.在存儲過程中使用表變量會減少存儲過程重新編譯的發生;
  c.表變量需要更少的鎖請求和日志資源;
  d.可以在表變量上使用UDF,UDDT,XML。

2.表變量的限制

與臨時表相比,表變量存在着如下缺點:
  a.在表變量上沒有統計信息,查詢優化器根據固定的預估值來選擇執行計划,在數據很多的情況下,會導致查詢優化器選擇很差的執行計划;
  b.不能直接在表變量上創建索引,但可以通過創建約束(主鍵、唯一)來建立索引;
  c.在DECLARE后,不能再對表變量進行更改;
  d.不能對表變量執行INSERT EXEC,SELECT INTO語句;
  e.不能通過EXEC或sp_executesql來執行牽涉到表變量的動態SQL語句,但如果表變量是在動態SQL語句內定義的,則可以。

3.那什么時候可以使用表變量

要使用表變量應該根據如下規則來判斷:
  a.表的行數;
  b.使用表變量能夠減少的重新編譯次數;
  c.查詢的類型和對索引或者統計信息的依賴程度;
  d.需要生用UDF,UDDT,XML的時候。
其實也就說,得從實際出發,根據具體的查詢,作出具體的選擇。但是,其中很關鍵的一點,如果表的行數非常多,使用表變量其實是更費資源的。有人提出了這樣的建議:對於行數較少的情況下(小於1000行)可以使用表變量;如果行數很多(有幾萬行),則使用臨時表。

因此,在實際的開發中,應通過分別使用臨時表或表變量進行對比后,才作出決定。


下面是一個例子,插入臨時表和表變量的數據有20多萬行,可以看到,使用臨時表的時間是使用表變量所花時間的1/5

'SalesOrderHeader'。掃描計數 3,邏輯讀取 130 次,物理讀取 9 次,預讀 43 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
'#SalesOrderDetail___________________________________________________________________________________________________00000000001F'。掃描計數 3,邏輯讀取 12331 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
'Worktable'。掃描計數 0,邏輯讀取 0 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

SQL Server 執行時間:
   CPU 時間 = 2281 毫秒,占用時間 = 19726 毫秒。
select with temporary table: 20140 ms

********************************************************************************

'SalesOrderHeader'。掃描計數 0,邏輯讀取 764850 次,物理讀取 17 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
'#4E88ABD4'。掃描計數 1,邏輯讀取 12331 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

SQL Server 執行時間:
   CPU 時間 = 4375 毫秒,占用時間 = 107160 毫秒。
select with table variable: 107160 ms

4.使用表變量的誤區

對於表變量,很多人認為,表變量和其他變量一樣,只存在內存中,其實這是不正確的,表變量也存在tempdb中。可以通過下面例子進行對比。

CREATE TABLE #TempTable (TT_Col1 INT)

DECLARE @TableVariable TABLE (TV_Col1 INT)

SELECT TOP 2 *

FROM tempdb.sys.objects

ORDER BY create_date DESC


name
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#03317E3D
#TempTable__________________________________________________________________________________________________________000000000003


#03317E3D就是剛創建的表變量;

5.其他

  表變量不受rollback影響,某些情況下會破壞數據的完整性。

CREATE TABLE #TempTable (TT_Col1 INT)
DECLARE @TableVariable TABLE (TV_Col1 INT)
INSERT #TempTable VALUES (1)
INSERT @T

a

 

 

本bleVariable VALUES (1)BEGIN TRANSACTION     INSERT #TempTable VALUES (2)      INSERT @TableVariable VALUES (2)ROLLBACKSELECT * FROM #TempTable/*TT_Col1-------1*/SELECT * FROM @TableVariable--返回了兩條記錄/*TV_Col1-------12*/6.參考http://support.microsoft.com/default.aspx?scid=kb;en-us;305977&Product=sql2kwww.sqlservercentral.com/articles/63472/databases.aspfaq.com/database/should-i-use-a-temp-table-or-a-table-variable.htmlwww.sqlservercentral.com/articles/Temporary+Tables/66720/

 

本文轉自:http://www.cnblogs.com/jokey/archive/2010/06/19/1760994.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM