这份 2007 年的白皮书比较了单个 select/insert/delete/update 和 range select 语句在组织为聚集索引的表上与在与 CI 相同的键列上具有非聚集索引的堆组织的表上的性能桌子。
通常,聚集索引选项在测试中表现更好,因为只需维护一个结构并且不需要书签查找。
本文未涵盖的一个可能有趣的案例是堆上的非聚集索引与聚集索引上的非聚集索引之间的比较。在那种情况下,我预计堆甚至可能会表现得更好,因为一旦在 NCI 叶级 SQL Server 有一个 RID 可以直接遵循,而不需要遍历聚集索引。
有没有人知道在这个领域已经进行了类似的正式测试,如果有,结果如何?
为了检查您的请求,我按照此方案创建了 2 个表:
调用的第一个表
heap
在该字段上有一个非聚集索引group
。调用的第二个表在调用clust
的顺序字段上有key
一个聚集索引,在该字段上有一个非聚集索引group
测试在具有 2 个超线程内核、4Gb 内存和 64 位 windows 7 的 I5 M540 处理器上运行。
选择性能
为了检查性能数字,我在堆表和集群表上执行了一次以下查询:
该基准测试的结果适用于
heap
:该表
clust
的结果是:SELECT WITH JOIN 性能
cmd.CommandText = "select * from heap/clust h join keys k on h.group = k.group where h.group between @id and @id+1000";
该基准测试的结果适用于
heap
:873 行有 > 0 CPU 并影响超过 0 行
该基准测试的结果适用于
clust
:865 行有 > 0 CPU 并影响超过 0 行
更新性能
第二批查询是更新语句:
该基准测试的结果
heap
:该基准测试的结果
clust
:删除基准
我运行的第三批查询是删除语句
此基准测试的结果
heap
:这个基准的结果
clust
:插入基准
基准测试的最后一部分是插入语句的执行。
插入堆/簇 (...) 值 (...), (...), (...), (...), (...), (...)
此基准测试的结果
heap
:此基准测试的结果
clust
:结论
尽管在使用聚集索引和非聚集索引访问表时(使用非聚集索引时)会进行更多的逻辑读取,但性能结果是:
Of course my benchmark was very limited on a specific kind of table and with a very limited set of queries, but I think that based on this information we can already start saying that it is virtually always better to create a clustered index on your table.
As we can see from the added results, the conclusions on the limited tests were not correct in every case.
The results now indicate that the only statements which benefit from the clustered index are the update statements. The other statements are about 30% slower on the table with clustered index.
Some additional charts where I plotted the weighted duration per query for heap vs clust.
As you can see the performance profile for the insert statements is quite interesting. The spikes are caused by a few data points which take a lot longer to complete.
正如索引女王金伯利·特里普(Kimberly Tripp)在她的博客文章“聚集索引辩论继续……”中很好地解释的那样,在数据库表上拥有一个聚集键几乎可以加快所有操作 - 而不仅仅是
SELECT
.与聚簇表相比,SELECT 在堆上的速度通常较慢,只要您选择一个好的聚簇键——比如
INT IDENTITY
. 如果您使用非常糟糕的集群键,例如 GUID 或具有许多可变长度组件的复合键,那么,但只有这样,堆可能会更快。但在那种情况下,你真的需要首先清理你的数据库设计......所以总的来说,我认为堆中没有任何意义——选择一个好的、有用的集群键,你应该在所有方面都受益。
Just happened to come across this article from Joe Chang that addresses this question. Pasted his conclusions below.