具有许多包含列的 SQL Server 范围索引

Posted

技术标签:

【中文标题】具有许多包含列的 SQL Server 范围索引【英文标题】:SQL Server wide indexes with many include columns 【发布时间】:2010-12-14 06:22:25 【问题描述】:

是否应该小心将过多的包含列添加到非聚集索引中?

我知道这将阻止对完全覆盖的查询进行书签查找,但我认为如果列不是静态的并且索引的额外总体大小会导致额外的物理读。

【问题讨论】:

【参考方案1】:

到目前为止,我都同意这两个答案,只是想补充两点:

为了覆盖索引,SQL Server 2005 引入了INCLUDE clause,这使得存储和使用更加高效。对于早期版本,包含的列是树的一部分,是 900 字节宽度的一部分,并使索引更大。

在使用 sp_spaceused 时,您的索引通常也比表大。数据库主要是读取(我在某处看到“85% 读取”),即使写入量很大(例如,INSERT 查找重复项,DELETE 检查 FK,UPDATE 与 WHERE 等)。

【讨论】:

【参考方案2】:

我同意 mjv - 对此没有真正简单快捷的答案 - 这是一种平衡行为。

一般而言,较少但较宽的索引比许多较窄的索引更可取,并且覆盖索引(带有包含字段)比必须进行书签查找更可取 - 但这只是概括,而且这些通常是错误的 :-)

除了测试和测量之外,您真的无能为力:

衡量您在感兴趣领域的表现 然后添加您的广泛和覆盖索引 再次测量,看看您是否 a) 在某些操作上获得了加速,并且 b) 剩余的性能不会受到太大影响

所有的猜测和试图弄清楚真的没有帮助 - 测量,做,再次测量,比较结果。这就是你所能做的。

【讨论】:

【参考方案3】:

您在问题中说过:索引中有许多索引和/或许多列的风险在于,在接收大量 CUD(创建/更新/删除)操作的数据库中维护索引的成本可能会变得很大.

选择正确的索引是一门艺术,它涉及平衡最常见的用例、存储问题(通常是低优先级问题,但在某些情况下很重要)以及 CUD 操作的性能问题。

【讨论】:

谢谢,我正在调整的环境包含一个 OLTP 数据库,还有一个 MI 数据库,它使用 OLTP 中的 select intos 构建其表。所以有点平衡的行为。希望将 MI db 移动到自己的环境中,并为其提供适当索引的 OLTP DB 副本。

以上是关于具有许多包含列的 SQL Server 范围索引的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 索引中include的魅力(具有包含性列的索引)

包含列的 SQL Server 索引 - 转换为 Oracle

包含列的索引:SQL Server索引的阶梯级别5

Sql Server关于create index include带有包含列的索引

包含列的索引:通往SQL Server索引级别5的阶梯

包含列的索引:SQL Server索引的阶梯级别5