【问题标题】:Does creating an indexed computed column to check for nulls buy me anything?创建索引计算列来检查空值对我有什么好处吗?
【发布时间】:2017-05-03 14:12:23
【问题描述】:

我的表中有可以为空的 DeletedDate 列,每当我针对这些表编写查询时,我通常都会检查以确保 DeletedDate IS NULL。我的想法是,如果我创建一个名为 IsDeleted 的索引的、持久的、计算的列,它可能会加快我的查询速度,因为它只需要检查一个位值而不是它索引一系列日期。

[IsDeleted] AS (isnull(CONVERT([bit],case when [DeletedDate] IS NULL then (0) else (1) end),(0))) PERSISTED NOT NULL,

但是,我查看了执行计划,它似乎仍在查看DeletedDate 列(我想,我可能读错了计划)。

对于只关心列是否为空的查询,这样做是否有任何意义,或者是否有不同的方法可以加快它的速度?

【问题讨论】:

  • 记录被删除的比例是多少?
  • @GordonLinoff 目前很少,但我们还没有完全启动应用程序
  • 如果是这种情况,那么您正在寻找性能改进的地方,但您还不知道您从一开始就有性能问题。这就是过早优化的定义。如果你要求的是纯粹的百科知识,恐怕找到答案的最好方法就是自己尝试并衡量它。
  • 查询表时,DeletedDate 上的谓词是 only 谓词,还是只是其中之一?
  • @BenThul 我们通常会过滤查询中的几列。

标签: sql sql-server sql-server-2008-r2 query-performance


【解决方案1】:

DeletedDate 上的索引(在大多数情况下)只有在绝大多数行未被删除时才有用。为什么?因为如果删除了很多记录,那么几乎每个数据页都会有已删除和未删除的记录。

索引不会减少需要阅读的页数。在这种情况下,扫描数据通常会更快。

一个主要的例外是聚集索引,其中DeletedDate 是第一列(或从该列派生的删除标志)。在这种情况下,未删除的记录和已删除的记录几乎总是在不同的数据页面上。因此,如果 5% 的记录被删除,您只需要读取大约 5% 的数据。

当然,聚集索引有开销。当一条记录被删除时,该记录实际上会在数据库中移动——导致多次读/写操作并增加碎片的可能性。使用聚集索引是否值得额外开销取决于您使用数据的方式、更新发生的频率以及其他类似因素。

【讨论】:

  • 绝大多数行都没有被删除(null DeletedDate)所以很高兴知道 DeletedDate 上的索引在我的查询中过滤该列时会有所帮助,但是你没有在您的答案中提及计算列。索引计算列会有帮助吗?
  • 过滤索引可能。大部分讨论取决于您使用的实际查询或查询。不要忘记没有什么是免费的。您在修改行时为索引“付费”。如果您真的想知道,答案只有一个 - 尝试并比较计划。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-03
  • 2023-04-07
  • 1970-01-01
  • 2012-01-22
  • 1970-01-01
相关资源
最近更新 更多