Sql-Server
觸發分區表和性能
我不確定我發現的是否是一個錯誤,但它確實看起來像。我找不到太多關於它的資訊,所以我決定把它放在這裡。
因此,簡而言之,在分區表上定義的觸發器中訪問內部表(
inserted
和)時,我面臨著糟糕的性能。deleted
為了測試這個問題,我創建了一些簡單的表,完全相同,但一個是分區的,另一個不是:
create table [dbo].[Test1]( [part_id] [int] not null, [id] [int] not null, [cost] [float] null, constraint [pk__Test1] primary key clustered ([part_id] asc, [id] asc) on ps_part(part_id) ); create table [dbo].[Test2]( [part_id] [int] not null, [id] [int] not null, [cost] [float] null, constraint [pk__Test1] primary key clustered ([part_id] asc, [id] asc) );
然後我用一些數據填充了表格。我現在沒有數據生成腳本,我只是使用了一些本地數據,但是這些表中有大約 473 個不同的分區和大約 383M 行。
然後我剛剛測試了這些表的更新速度有多快,使用非常簡單的查詢,例如
update dbo.Test1 set cost = cost + 0.1 where part_id = ??; update dbo.Test1 set cost = cost - 0.1 where part_id = ??; update dbo.Test2 set cost = cost + 0.1 where part_id = ??; update dbo.Test2 set cost = cost - 0.1 where part_id = ??;
結果是分區表的邏輯平均更新時間約為2 秒,非分區表的平均更新時間約為4 秒。
然後我在兩個表上創建了簡單的觸發器
alter trigger [dbo].[Test1__changed] on [dbo].[Test1] after insert,update,delete as begin set nocount on; select a.part_id into #temp11111111 from ( select r.part_id from inserted as r union select r.part_id from deleted as r ) as a; end
之後我嘗試了相同的測試查詢,結果非常奇怪 - 在分區表上,查詢平均需要3 分鐘才能完成,而在非分區表上,時間與沒有觸發器的情況相似 -大約4 秒。
你知道為什麼會發生這種情況嗎?有什麼辦法可以解決這個問題?
此問題記錄在Alex發現的KB 2606883中的 SQL Server 2012 中。
我在 SQL Server 2019 中重現了該問題,並驗證設置跟踪標誌 2470 解決了它。
我不清楚修復的確切性質是什麼,以及為什麼這不是更高版本中產品的預設行為。
對於我的範例數據(3000 萬行均勻分佈在 700 個分區和一個空分區中),這使插入掃描和刪除掃描所需的時間從每個 > 4 秒減少到每個 0.021 秒。
開啟和關閉 TF 的執行計劃(包括執行時統計資訊)在此處。在這兩個計劃中,刪除/插入的掃描仍然說他們訪問所有 701 分區。