当贡献列已经是唯一的时,计算列上的唯一索引

And*_*y M 4 index sql-server sql-server-2014 unique-constraint computed-column

我有一个这样的表:

CREATE TABLE
  dbo.DiscountBarcodeList
(

  ID int NOT NULL IDENTITY
    CONSTRAINT PK_DiscountBarcodeList
    PRIMARY KEY CLUSTERED

, Discount int NOT NULL
    CONSTRAINT FK_DiscountBarcodeList_Discount
    FOREIGN KEY REFERENCES dbo.Discount (ID)

, CodeNumber int NOT NULL

, AssignedEntity int NULL
    CONSTRAINT FK_DiscountBarcodeList_AssignedEntity
    FOREIGN KEY REFERENCES dbo.Entity (ID)
    ON DELETE SET NULL

, BarcodeID AS
    CONVERT(
      char(10)
    , CAST(Discount AS binary(2)) + CAST(CodeNumber AS binary(3))
    , 2)

, CONSTRAINT UQ_DiscountBarcodeList_DiscountCodeNumber
    UNIQUE NONCLUSTERED 
    (
      Discount  ASC
    , CodeNumber ASC
    )

);
Run Code Online (Sandbox Code Playgroud)

该表将保存预先CodeNumber分配给 s 的 s并根据需要分配给 s。虽然不是在数据库级别,但和的值将分别限制为 2 字节和 3 字节。这些限制与 的唯一约束一起,将有效地使生成的值也唯一。DiscountEntityDiscountCodeNumber(Discount, CodeNumber)BarcodeID

该表的使用方式是,应用程序将传递 a@BarcodeID来查找 an@Entity以分配给它。如果查找成功,则该行将Entity被设置为@Entity,或者应用程序将收到通知,该行@BarcodeID已被采用,大致如下:

BEGIN TRANSACTION;

UPDATE
SET
  @OldEntity = Entity
, Entity = @Entity
WHERE
  BarcodeID = @BarcodeID
;

IF @OldEntity IS NULL
BEGIN
  COMMIT TRANSACTION;
  ...  /* report success */
END

ELSE
BEGIN
  ROLLBACK TRANSACTION;
  ...  /* report failure */
END;
Run Code Online (Sandbox Code Playgroud)

现在我想做BarcodeIDsargable。因为我知道该列只有唯一值,所以我正在考虑使索引唯一,因为我认为这可以使我的查找更有效。另一方面,我担心必须检查生成的值的唯一性,这在这里是多余的,因为唯一性已经得到保证。

是否有可能以某种方式判断计算列上唯一索引的好处(如果有的话)是否会超过(在这种情况下不必要的)唯一性检查的可能开销?或者至少对于像我这样的场景可以确定这一点吗?或者我只是想太多了?

Pau*_*ite 7

这是一个只有您才能真正决定的权衡。

您已经将Split-Sort-Collapse运算符组合添加到任何更新DiscountCodeNumber避免错误的瞬态唯一键违规的计划中。添加唯一索引BarcodeID将添加第二个这样的运算符组合来更新计划,以及一个 Eager Spool 来驱动它们。如果需要的工作表超出服务器的限制,则此类更新也可能会失败并出现错误。这些是主要的缺点。

从好的方面来说,您可以获得可查找的索引,并可能获得更好的信息供优化器一般使用。您还拥有实际的唯一性保证,而不是稍微模糊的暗示保证。

就我个人而言,我可能会添加唯一索引并测试工作负载,看看性能影响是否可以忍受。

相关问答:


归档时间:

查看次数:

203 次

最近记录:

1 年,7 月 前