【问题标题】:PERSISTED Computed Column vs. Regular ColumnPERSISTED 计算列与常规列
【发布时间】:2015-07-01 02:57:39
【问题描述】:

我有一个高性能数据库(在 SQL Server 2012 上)。我的一个观点有一个虚拟列,由一个内联标量值 UDF 表示,该 UDF 计算来自前一列值的自定义哈希。我将此计算从视图移到了一个基础表中以提高性能。我在表中添加了一个新的计算列并保留了数据。然后,在该列上创建索引并在相应的视图中引用它(基本上将逻辑从视图迁移到表中)。

现在我想知道为什么不向表中添加一个常规的 VARCHAR(32) 列而不是计算的 PERSISTED 列?我可以使用上述 UDF 在此列上为所有新插入创建一个 DEFAULT 并重新计算历史记录。

具有 PE​​RSISTED 数据的索引计算列与常规 NC 索引列相比有什么优势吗?

谢谢。

【问题讨论】:

  • 什么是“常规 NC 索引列”?
  • 在这种情况下,VARCHAR(32) 数据类型的新列具有非聚集索引。我想它应该显示为 SELECT * FROM sys.columns WHERE is_computed 1.... 我理解你的问题吗?
  • @GordonLinoff 我认为他的意思是一个非常普通的列,上面有一个非聚集索引。然后他将一些计算结果写入该列,以加快查询速度。
  • @Milan:你不能在 SQL Server 中使用 UDF 作为默认值
  • @Quassnoi 。 . .根据文档,您可以(msdn.microsoft.com/en-us/library/ms174979(v=sql.110).aspx)。

标签: sql sql-server tsql sql-server-2012


【解决方案1】:

如果它所基于的字段数据发生更改,计算列将使您的字段保持最新。如果没有为该字段提供值,则仅添加一个默认值将在插入时更新该字段。

如果您知道您的数据不会改变(我认为您是在暗示但没有在您的问题中指定),那么它们在功能上对您来说是相同的。尽管可以防止使用不正确的值意外更新字段(绕过默认值),但可能会首选计算列。此外,任何其他开发人员都清楚该字段的用途。

【讨论】:

    【解决方案2】:

    您可以切换到具有默认值或插入触发器的“普通”列。一个潜在的问题是,与计算列不同,任何具有插入/更新访问权限的人都可以(可能意外地)更改列的值。

    无论哪种方式,性能都将相同。本质上,这就是数据库在后台使用持久计算列所做的事情。作为开发人员,持久计算的列在意图上比默认值更清晰。默认值意味着它是许多可能值之一,而不是唯一可能值。

    请务必使用 SchemaBinding 声明 UDF。这将允许 SQL Server 确定函数是否具有确定性并将其标记为确定性。在某些情况下,这可以改进查询计划优化。

    【讨论】:

    • 触发器将比默认/计算列有更多的开销,因为触发器的存在需要inserted/deleted 表。
    【解决方案3】:

    没有性能差异。但是,就数据库设计而言,将预先计算的列放在持久化视图中会更优雅。

    【讨论】:

    • ...好的,但是考虑到对基础表的频繁读写,这不会影响性能吗?
    • @Milan - 如果对基础表进行频繁的 R/W 操作,为什么会有任何不同?唯一额外的 W 活动是保持列同步,无论如何您都需要这样做。
    • @Milan 不,因为引擎足够聪明,只更新您更改的行。好吧,唯一的其他区别是持久化视图存储在单独的表中。因此,在某种程度上,您可以将其存储在单独的磁盘上,例如 - 这样您可以稍微提高性能。 (对于这种情况,我说的是持久化的 VIEW,而不是持久化的计算表列)。
    • 并发索引(在视图和基础表上)不会造成不必要的开销吗?
    猜你喜欢
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多