SQL高級知識——臨時表的用法

SQL 數據庫 Microsoft SQL Server SQL數據庫開發 2019-05-27

臨時表定義

臨時表與實體表類似,只是在使用過程中,臨時表是存儲在系統數據庫tempdb中。當我們不再使用臨時表的時候,臨時表會自動刪除。

臨時表分類

臨時表分為本地臨時表和全局臨時表,它們在名稱、可見性以及可用性上有區別。

臨時表的特性

對於臨時表有如下幾個特點:

  • 本地臨時表就是用戶在創建表的時候添加了"#"前綴的表,其特點是根據數據庫連接獨立。只有創建本地臨時表的數據庫連接有表的訪問權限,其它連接不能訪問該表;
  • 不同的數據庫連接中,創建的本地臨時表雖然"名字"相同,但是這些表之間相互並不存在任何關係;在SQLSERVER中,通過特別的命名機制保證本地臨時表在數據庫連接上的獨立性,意思是你可以在不同的連接裡使用相同的本地臨時表名稱。
  • 全局臨時表是用戶在創建表的時候添加"##"前綴的表,其特點是所以數據庫連接均可使用該全局臨時表,當所有引用該臨時表的數據庫連接斷開後自動刪除。
  • 全局臨時表相比本地臨時表,命名上就需要注意了,與本地臨時表不同的是,全局臨時表名不能重複。
  • 臨時表利用了數據庫臨時表空間,由數據庫系統自動進行維護,因此節省了物理表空間。並且由於臨時表空間一般利用虛擬內存,大大減少了硬盤的I/O次數,因此也提高了系統效率
  • 臨時表在事務完畢或會話完畢數據庫會自動清空,不必記得用完後刪除數據。


本地臨時表

本地臨時表的名稱以單個數字符號"#" 打頭;它們僅對當前的用戶連接(也就是創建本地臨時表的connection)是可見的;當用戶從 SQL Server 實例斷開連接時被刪除。

本地臨時表實例

我們以Customers表為實例,表數據如下:

SQL高級知識——臨時表的用法


我們新建一個連接,每當“新建查詢”就代表打開了一個連接,連接的ID就是sa後面的數字,我們的這個連接ID是57.

SQL高級知識——臨時表的用法


下面我們在這個查詢頁面建立一個臨時表。

SELECT * INTO #Customers FROM Customers

這樣我們就建好了一個臨時表,可以查詢一下臨時表#Customers的數據。與Customers內容一致。

SELECT * FROM #Customers


SQL高級知識——臨時表的用法


如果我們再打開一個頁面,同樣查詢#Customers表會怎麼樣呢?

SQL高級知識——臨時表的用法


我們在新開的查詢頁面執行上述查詢語句,得到的結果如下:


SQL高級知識——臨時表的用法


說明本地臨時表不支持跨連接查詢。只能在當前連接(或者當前查詢頁面)訪問。

那本地臨時表具體在什麼地方呢?它又是怎麼存放的呢?

SQL高級知識——臨時表的用法

這就是我們剛才建立的臨時表,在系統中並不是用#Cusomters表示的。

全局臨時表

全局臨時表的名稱以兩個數字符號 "##"打頭,創建後對任何數據庫連接都是可見的,當所有引用該表的數據庫連接從 SQL Server 斷開時被刪除。

全局臨時表實例

我們還是按照上面的步驟走一遍

先打開一個查詢頁面,輸入如下查詢語句:

SELECT * INTO ##Customers FROM Customers

執行完上面的查詢語句後,我們關掉查詢頁面,再重新開一個頁面查詢##Customers中的內容

SELECT * FROM ##Customers

結果如下:

SQL高級知識——臨時表的用法

此時並不會像本地臨時表那樣報錯了。

全局臨時表的位置如下:


SQL高級知識——臨時表的用法


它的名稱與我們自定義的名稱一致,系統不會額外添加其他信息。

臨時表的用途

介紹完臨時表,我們來說說如何用它來進行優化

臨時表的優化一般使用在子查詢較多的情況下,也稱為嵌套查詢。我們寫如下子查詢:

SELECT * FROM sales.Temp_Salesorder
WHERE SalesOrderDetailID IN
(SELECT SalesOrderDetailID FROM sales.SalesOrderDetail
WHERE UnitPrice IN
(SELECT UnitPrice FROM sales.SalesOrderDetail WHERE UnitPrice>0)
)


(提示:代碼可以左右滑動)

這是一個比較簡單的兩層嵌套子查詢,我們看一下執行情況:

SQL高級知識——臨時表的用法


可以看到這裡的邏輯讀取是比較高的。

我們用臨時表重新來看下執行情況如何,我們將第一二層的查詢結果插入到#temp中,然後從臨時表中查詢結果。

SELECT SalesOrderDetailID INTO #temp FROM sales.SalesOrderDetail
WHERE UnitPrice IN (SELECT UnitPrice FROM sales.SalesOrderDetail WHERE UnitPrice>0)
SELECT * FROM sales.Temp_Salesorder
WHERE SalesOrderDetailID IN
(SELECT SalesOrderDetailID FROM #temp)


執行情況如下:


SQL高級知識——臨時表的用法


SQL高級知識——臨時表的用法


相比上一次的邏輯讀,成倍的減少了邏輯讀取次數。在對查詢的性能進行調節時,如果邏輯讀值下降,就表明查詢使用的服務器資源減少,查詢的性能有所提高。如果邏輯讀值增加,則表示調節措施降低了查詢的性能。在其他條件不變的情況下,一個查詢使用的邏輯讀越少,其效率就越高,查詢的速度就越快。

因此我們可以看出臨時表在比較複雜的嵌套查詢中是可以提高查詢效率的。

批註

臨時表不管是在SQL Server還是其他平臺都有使用,其在查詢優化方面可以極大的提高查詢效率,而SQL Server平臺的臨時表相比其他平臺更容易創建和使用,其優越性不言而喻。所以如果平時工作或學習過程中,臨時表可以作為一個必備技能經常使用。

相關推薦

推薦中...