在主键上使用包含列的第二个索引有什么好处?

Gre*_*reg 7 index sql-server index-tuning sql-server-2012

我正在查看我们的数据库并注意到在特定表上我们有以下索引:

Col1    INT IDENTITY(1,1) Primary Key
Col2    INT
...
about 15 more columns
....
ColN   VARCHAR(50)
....
another 10 more columns
Run Code Online (Sandbox Code Playgroud)

除了标准的主键聚集索引之外Col1,我们还有以下索引:

create nonclustered index [iTable-Col1] ON [dbo].[Table1]
(
    Col1
)
include ( ColN )
Run Code Online (Sandbox Code Playgroud)

我们定期搜索Col1并且只想检索ColN. 该索引确实得到使用,因为它是包含满足查询所需的所有数据的最小索引。

我的问题是,这个索引对 SQL Server 有什么好处吗?我们最好放弃它并只在聚集索引上进行搜索吗?

我唯一的想法是这个索引比聚集索引(25mb vs 300mb)小得多,这可能会使搜索和/或缓存更快。

如果有任何区别,服务器是 SQL Server 2012。

Jon*_*gel 8

大多数情况下,这种类型的索引仅对针对这些列的索引扫描有用。

叶级别以上的索引树结构通常在树级别方面非常相似,因此如果是这种情况,则在导航树以进行查找操作(也不会扫描)时几乎没有或没有性能差异。如果你想学习索引内部的基础知识,我这里有一个视频可以帮助你。

无论如何,回到扫描。这个索引有用的原因不是索引本身,而是关于为什么扫描聚集索引(或将这些数据页保留在内存中)。如果其他列使表相对较宽(根据您提供的大小,我会说它们确实如此,尽管目前尚不清楚该表在整个数据库上下文中的大小),则窄索引在某些情况下可能会有所帮助. 频繁的扫描(或对许多不同的键值进行查找)往往会将整个索引保留在内存中,因此索引越大,其他对象的内存空间就越少,当然,如果缓冲池是冷的。

尽管这是一个罕见的用例(我已经做过一次或两次我记得),但这种类型的索引的最大好处是它将极大地帮助想要使用合并连接来连接此表的查询。(注意:如果索引扫描不合适,首先优化查询!)在查询计划中,在合并连接之前对聚集索引的扫描或对非聚集索引的扫描和排序可以指示何时可能是个好主意。但同样,这是罕见的。查询应该足够频繁地执行,或者基表足够昂贵以保持卡在内存中(即,您不需要它一直存在),以证明索引的额外存储和维护是合理的。

如果您不确定现在如何使用此索引,请查看 DMV sys.dm_db_index_usage_stats。请记住,计数会在服务器重新启动时重置,因此如果您正在考虑删除索引,请确保它在整个业务周期内都没有用。