强制 SQL Server 使用碎片索引?

mik*_*net 7 performance index sql-server index-tuning sql-server-2017

我有一个非常大的表(> 10M 行),经常进行 crud 操作。它有适当的索引,但它们很快就会碎片化。如果没有定期的索引重组/重建维护计划,索引碎片很容易超过 90%。

现在我已经通过每天重新组织索引和每周重建来解决这个问题。我还使用了填充因子等来降低碎片化。

我的主要问题是,当索引过于分散时,SQL Server 会忽略索引并执行全表扫描。当这种情况发生时,它几乎杀死了应用程序,因为重复扫描如此大的表真的很繁重。我很确定在这些情况下使用碎片索引会更快。

有没有办法让 SQL Server 使用索引而不管它的碎片如何?

Eri*_*ing 14

索引提示

您可以使用索引提示来做到这一点:

SELECT *
FROM dbo.Users AS u WITH (INDEX = ix_definitely_an_index)
WHERE u.Reputation = 2;
Run Code Online (Sandbox Code Playgroud)

缺点是:

  • 可能会更改很多代码
  • 如果您重命名索引,则会中断
  • 如果您更改索引定义,它可能不再是最好使用的索引

计划指南

您还可以使用Plan Guide,它可以设置您想要的计划。

缺点是:

  • 变化无常;如果您的查询不完全相同,您的计划可能不会被使用
  • 设置起来很困难;你必须让一切都完全正确
  • 也是与索引提示相同的东西,所以呃......这很粗糙。

查询存储?

由于您使用的是 SQL Server 2017,您可以使用查询存储来强制执行计划。这比使用计划指南容易得多,但您最终可能会得到一个意想不到的计划

缺点:

  • 和上面一样的东西
  • 必须启用查询存储,如果您还没有使用它
  • 必须查询查询存储以查看强制计划是否失败

备择方案

在不知道更多的情况下,我可能更热衷于调查索引使用是否因其他原因而改变,例如参数嗅探