Sql-Server

我應該使用臨時表還是加入

  • February 3, 2022

我正在 sql server 2019 中創建一個儲存過程,該過程需要使用多個 select 語句來獲取父行,然後是其相關數據。我有父級的主鍵聚集值,所以第一個查詢最多返回 1 行。

我應該為第一個查詢選擇所有內容到臨時表中,然後將後續查詢加入臨時表,還是應該繼續加入原始表?

我不確定創建臨時表的成本是否會掩蓋重複加入實際表的成本。

我查看了性能計劃,結果它們是相同的,讀取/掃描和時間的統計數據也大致相同。

我想我想弄清楚的是,如果我使用臨時表,它會減輕原始表的壓力嗎?原始表被大量讀取和寫入。

我應該注意,這些語句將在儲存過程中,因此我可能會從臨時對象記憶體中獲得提升。

假設表 A 有 > 100 萬行,並且 TableB 中每個條目有 0-10 行,TableC 中每個條目有 0-10 行

簡單的表格圖

沒有臨時表的查詢

declare @taID bigint=123

select
   ta.*
from
   TableA ta
where
   ta.ID=@taID


select
   tb.*
from
   TableA ta
   inner join TableB tb on ta.ID=tb.TableAID
where
   ta.ID=@taID

select
   tc.*
from
   TableA ta
   inner join TableC tc on ta.ID=tc.TableAID
where
   ta.ID=@taID

帶有臨時表的查詢

declare @taID bigint=123

select * 
into #tmpA
from
   TableA ta
where
   ta.ID=@taID

select * from #tmpA

select
   tb.*
from
   #tmpA ta
   inner join TableB tb on ta.ID=tb.TableAID

select
   tc.*
from
   #tmpA ta
   inner join TableC tc on ta.ID=tc.TableAID
  1. 正如您從子表中知道的 PK 一樣,連接是點。
  2. 即使有連接,#tmpA 和 TableA 之間的差異為零,甚至可能有利於 TableA,具體取決於。如果需要,您的第一個選擇會在記憶體中進行物理讀取,然後是它唯一的邏輯讀取,並且這些讀取也必須使用臨時表完成,除了臨時表,您需要創建它並插入數據

我認為您不需要使用臨時表。這只是浪費寫IO。

我要做的就是在歸檔的 TableAID 上覆蓋 tableB 和 tableC 中的索引。

如果針對 A 表的更新正在生成高鎖,您最終可以評估 SNAPSHOT ISOLATION LEVEL。

引用自:https://dba.stackexchange.com/questions/286105