Sql-Server

可信約束,不可複制

  • November 12, 2018

版本和內部版本:SQL Server 2005 SP4 (9.0.5000)

作為某種免責聲明,我提出這個問題是為了引起對該主題的一些討論和/或辯論。我不知道是否真的有一個正確的答案,或者正確的答案是否是一個大胖子“It Depends”。因此,我會很慢地接受答案,除非提供了無法被反對意見反駁的明確證據。

該問題涉及 OBJECTPROPERTY CnstIsNotTrusted 和 OBJECTPROPERTY CnstIsNotRepl,以及它們之間的關係。CnstIsNotTrusted 屬性在添加或檢查約束時由 WITH CHECK|NOCHECK 控制。CnstIsNotTrusted 屬性意味著在不檢查現有行的情況下啟用了約束;因此,約束可能不適用於所有行。當為 true 時,約束不能用於查詢優化。例如,我有一個 Person 表,其 LastName 的檢查約束確保 LastName LIKE ‘Mc%’。如果 CnstIsNotTrusted = 1,那麼如果我搜尋 LastName = ‘Smith’,查詢計劃仍然需要掃描/查找索引。如果 CnstIsNotTrusted = 0 則執行計劃甚至不會觸及表格。這已在此處得到證明:

https://sqlserverfast.com/blog/hugo/2007/03/can-you-trust-your-constraints/

OBJECTPROPERTY CnstIsNotRepl(DDL 中的 NOT FOR REPLICATION)強制在複製同步期間不檢查約束。更準確地說,將檢查發布方,但不會檢查訂閱方。這確保不會多次檢查相同的約束。但是,使用 NOT FOR REPLICATION 將使您的約束不受信任。

我的問題是,為了有時獲得更有效的執行計劃,不使用 NOT FOR REPLICATION 是否值得額外的 CPU 週期?

NOT FOR REPLICATION 適用於這種情況:

  1. 您有一個帶有 FK 到 Person 表的 Order 表。
  2. Order 表在第 1 號出版物中,Person 表在第 2 號出版物中。
  3. Order pub 和 Person pub 將在不同的時間發生。因此,如果 Order 表中的一些新記錄被向下複製到訂閱者,並且 Person 表缺少新 Order 所針對的人,那麼您不希望複製插入在訂閱者處失敗。相反,可以相信新的 Person 記錄會在某個時候下降,因為在 Publisher 處使用了 FK。
  4. 在訂閱者處,如果您插入 Order 記錄,FK 將檢查 Person 記錄是否存在。

我將始終堅持這一政策,並且僅將 NOT FOR REPLICATION 用於 FK 與不同出版物中的表相關的目的,而不是用於查詢計劃優化的目的。

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