Sql-Server

觸發分區表和性能

  • July 7, 2022

我不確定我發現的是否是一個錯誤,但它確實看起來像。我找不到太多關於它的資訊,所以我決定把它放在這裡。

因此,簡而言之,在分區表上定義的觸發器中訪問內部表(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 分區。

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