非聚集索引和复合主键之间的性能

Posted

技术标签:

【中文标题】非聚集索引和复合主键之间的性能【英文标题】:Performance between non-clustered index and composite primary key 【发布时间】:2018-09-06 15:08:52 【问题描述】:

我正在从包含以下类型列的复合键更改 SQL Server 2014 数据库的主键:

VARCHAR(10), INT, DATETIME

到一个复合键包含

INT, DATETIME

其中第二个键中的INT 是一个新列,是VARCHAR(10)INT 的先前组合的哈希。我还不能更改主键,所以在添加新列后,我创建了一个索引,将来会是新的主键 (INT, DATETIME):

CREATE UNIQUE NONCLUSTERED INDEX MyIndex 
     ON MyTable(MyIdCol, MyDateCol)

此时,我将阅读器切换为使用此索引而不是主键来获取数据。一切正常,但性能严重下降(时间增加了一倍多)。

此时,我尝试将 (INT, DATETIME) 设为新的主键。查询速度提高了 30-40%,但老实说,我认为在这个新主键上查询会比在其中包含 VARCHAR 的旧主键快得多(当然我可能在我的基准测试中搞砸了- 数据库模式非常复杂,需要 24 小时来设置测试用例)。

不幸的是,我刚刚在生产环境中删除了主键 - 我需要一个同时拥有旧主键和新唯一索引的阶段,因此我需要在查找该索引时获得类似的性能。我需要关于看什么的方向。老实说,我不完全理解为什么在 INT,DATETIME 上查询甚至只是作为索引而不是主键比 VARCHAR,INT,DATETIME 主键慢得多。

【问题讨论】:

您能否获取查询的实际执行计划并将其粘贴到此站点:brentozar.com/pastetheplan 有执行计划吗?选择代码?表 DDL? @MJH 查询作为 XML 执行。以下是实际的执行计划:brentozar.com/pastetheplan/?id=BJzNLaRwm @MJH 这是使用将成为新主键的索引进行查询时的执行计划。 @IvanStarostin brentozar.com/pastetheplan/?id=BJzNLaRwm(见上文) 【参考方案1】:

评论太长了。

“慢”有多慢?搜索非聚集索引时,数据库引擎需要在索引中找到行引用(相当快),然后加载数据页来获取行。

使用聚集索引搜索时,无需加载数据页。

在获取多行时,差异可能会更加明显,因为聚集索引将数据放在相同的数据页上。非聚集索引很可能从不同的页面获取每个被检索的项目(直到某一点)。

您可以通过仅获取索引中的列来比较性能差异。这可能不是您想要的,但它是一个可行的性能比较。这两个索引之间应该是相似的。

可能解释了性能上的差异。如果是这样,那么这没什么好担心的,因为这是不使用聚集索引时的预期开销。一般来说,这对于速度较快的查询而言相对较大,而对于较慢的查询而言则不太重要。

【讨论】:

以上是关于非聚集索引和复合主键之间的性能的主要内容,如果未能解决你的问题,请参考以下文章

复合非聚集索引和覆盖索引有啥区别

MySQL中怎样创建聚集索引和非聚集索引,求创建这两种索引的SQL语句。谢谢

聚集索引非聚集索引

聚集索引非聚集索引主键

数据库索引聚集/非聚集索引,索引和锁

SQL有三个类型的索引,唯一索引 不能有重复,但聚集索引,非聚集索引可以有重复