Sql-Server-2005

SQL Server 觸發器的性能

  • December 6, 2021

我來自 Oracle/PostgreSQL 背景,很難應對 SQL Server 觸發器實現的限制。

datetime如果不同列的值發生變化,我想更新兩個不同的列。這是為了記錄行的兩個具體狀態變化。

現在 SQL Server 既沒有行級觸發器,也沒有before update觸發器。所以我的理解是我需要加入插入和刪除以找出是否發生了狀態變化以及發生了哪些狀態變化,然後對正在更新的表執行“定期”更新。

我的觸發器目前看起來像這樣:

create trigger ord_status_history_trigger
 on jobs
AFTER UPDATE
AS
 IF ( UPDATE(order_status) )
 BEGIN
   update jobs
     set  transfercomplete = case
                               when o.order_status = 'initial' and n.order_status = 'sent' then current_timestamp
                               else n.transfercomplete
                             end,
          installcomplete = case
                              when o.order_status = 'delivered' n.order_status = 'installed' then current_timestamp
                              else n.installcomplete
                           end
     from inserted n
       join deleted o on o.jobid = n.jobid
       join jobs aj on aj.jobid = n.jobid;
 END

我的問題是:這個觸發器是否有效地導致表上的兩個更新?

第一個是觸發更新,第二個是觸發器執行的更新?

或者 SQL Server 是否足夠聰明,可以將其合併到對基表的單個更新中(基本上就像BEFORE UPDATEPostgreSQL 中的觸發器一樣)

我會在這裡造成潛在的性能瓶頸嗎?

我們也可以在應用程序中設置這些時間戳,但是如果我們可以將其委託給數據庫會更好,這樣我們就可以確保永遠不會忘記這一點。

您的觸發器在表上發生更新後執行。如果您在觸發器中再次更新表,則會執行新的更新。另請參閱有關RECURSIVE_TRIGGERS的討論。

如果您想在更新之前執行程式碼,您必須創建一個INSTEAD OF 觸發器

是否必須進行兩次更新而不是一次更新會成為瓶頸,完全取決於觸發器中更新的效率,當然還有這個 UPDATE 是否已經在關鍵路徑上。您可能在作業 id 上有一個主鍵,頁面在緩衝池中很熱,並且您不能有鎖衝突。所以基本上只取決於a)您的日誌接受寫入的速度和b)版本儲存(為已刪除和插入的偽表提供服務)是否可以跟上。

如果你問我:這樣的業務邏輯狀態管家屬於應用程序,而不是觸發器……

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