用过滤的(非空值)索引替换索引有什么影响?

Kah*_*ahn 10 index sql-server filtered-index

我们的项目运行着一个非常大、非常复杂的数据库。所以大约一个月前,我们注意到包含空值的索引列使用的空间变得太大。作为对此的回应,我编写了一个脚本,该脚本将动态搜索包含超过 1% 的空值的所有单列索引,然后在该值不为空的情况下删除并重新创建这些索引作为过滤索引。这将删除并重新创建整个数据库中的数百个索引,通常会释放整个数据库使用的近 15% 的空间。

现在我有两个问题:

A) 以这种方式使用过滤索引的缺点是什么?我认为它只会提高性能,但是否涉及任何性能风险?

B) 我们在删除和重新创建索引时收到错误(“不能删除索引 XYZ,因为它不存在或您没有权限”),即使在事后检查时,一切都完全按预期进行。这怎么会发生?

谢谢你的帮助!

编辑:回应@Thomas Kejser

嗨,谢谢,但事实证明这是一场灾难。当时我们不明白一些事情,例如:

  1. 在查询期间,SQLOS 在确定它不能使用 NULL 值连接表列之前制定索引计划。IE,您确实需要有一个 WHERE 子句过滤器来拟合查询中使用的每个过滤索引的索引,否则根本不会使用该索引。
  2. 删除和创建索引并在之后再次冗余更新他们的统计信息仍然可能不足以生成更新的计划,我们假设他们会这样做。在某些情况下,似乎只有足够高的工作负载才会迫使 SQL Server 重新评估计划。
  3. 执行计划器的功能有一些奇异的东西,仅凭常识和逻辑就很难确定。甚至有数以千计的代码隐藏生成的不同查询的变体,看似无用的索引可以帮助某些最终在关键查询中使用的统计信息和查询计划。

最终,这些更改被还原。因此过滤索引是一个强大的工具,但您需要真正了解从这些列中提取的数据。除了空间问题之外,普通索引很容易应用,过滤索引代表了非常定制的解决方案。它们当然不是常规索引的替代品,而是在需要它们的特殊情况下对它们的扩展。

Tho*_*ser 8

非常有趣的做法。我对创造力的赞许。

既然你回收了空间,我假设原始索引不再存在?过滤索引的缺点是:

实际上,这意味着您必须对过滤索引非常小心,因为它们通常会导致糟糕的查询计划。我不会说它们无用,但我认为它们是对传统索引的补充,而不是作为替代品(正如您正在尝试做的那样)。