前天发表了篇文章叫《小议数据库主键选取策略(原创)》,随即有网友提出了反驳意见《反驳 吕震宇的“小议数据库主键选取策略(原创)” 》,看到后,我又做了做实验,在这里将实验结果以及我的思考再向大家汇报一下:
首先感谢twodays提出意见,说实在的,关于COMB与GUID的效率差异是否有10到30倍我没有做实验,我会在以后掌握确切数据后修改这个结果。twodays的实验我做了,在我的机器上(P IV 2.0G,512M DDR400内存)实验结果如下:
int类型为主键的表插入开始时间:07 19 2004 8:19PM
int类型为主键的表插入结束时间:07 19 2004 8:19PM
int类型为主键的表插入共用时间:5600毫秒
GUID(聚簇索引)类型为主键的表插入开始时间:07 19 2004 8:19PM
GUID类型(聚簇索引)为主键的表插入结束时间:07 19 2004 8:19PM
GUID类型(聚簇索引)为主键的表插入共用时间:6030毫秒
GUID(非聚簇索引)类型为主键的表插入开始时间:07 19 2004 8:19PM
GUID类型(非聚簇索引)为主键的表插入结束时间:07 19 2004 8:19PM
GUID类型(非聚簇索引)为主键的表插入共用时间:5746毫秒
COMB类型为主键的表插入开始时间:07 19 2004 8:19PM
COMB类型为主键的表插入结束时间:07 19 2004 8:19PM
COMB类型为主键的表插入共用时间:6066毫秒
从中看到似乎COMB是最慢的。但是这又有多少是因为计算COMB数据而造成的呢?
![](/Images/OutliningIndicators/None.gif)
而且,作为聚簇索引与非聚簇索引的概念,我想仅仅MSDN中的一段话是不足以说明问题的。我想从以下几个方面重新论述一下:
一、主键的作用:
“反驳”中有这样两句话:“采用非聚簇索引也有不方便的地方,那就是不能排序了”,“如果只是为了需要一个唯一标示符来做为主键,并且在这个字段上不需要做什么排序呀,范围对比等操作的话,那么我们可以放心大胆的使用GUID来做为主键”。那么主键的作用是什么呢?我认为主键有这么几个作用:
- 实现实体完整性约束,确保不会出现重复;
- 在参照完整性中充当被参照对象,需要与外键进行连接,当然从优化角度出发也需要排序了;
- 在编程建立业务实体对象时,是一个很好的检索出发点;
- 在删除、更新操作时可以出现在WHERE短语中表示操作的对象(显然又会进行检索)。
所以,主键一个必不可少的功能就是排序,提高检索效率。不过我认为“反驳”中有一点搞错了,那就是在排序问题上,实际上非聚簇索引主键在排序上不输给聚簇索引主键多少(这一点请看论述二)。
二、聚簇索引与非聚簇索引的本质区别是什么
因为“反驳”中仅仅做了插入实验,所以我认为不足以说明问题。很多人并没有真正了解聚簇索引与非聚簇索引的本质区别,以至于对实验结果产生误解。为此我新写了一篇文章《聚簇索引与非聚簇索引的区别以及SQL Server查询优化技术》,在这里详细进行了论述,看完后,很多事情也就不言自明了。
三、应当如何设计实验检测COMB与GUID的效率问题
设计一个实验应当能够准确衡量被测试的内容,尽可能少的减少其它因素带来的偏差。我认为“反驳”中的实验仅仅测试了插入性能,而且没有把计算COMB的造成的性能损失因素排除在外,另外主键与外键连接时的性能没有测试,排序性能也没有测试。昨天晚上我重新设计了实验,并得到了新的实验结果。实验过程以及实验结果会随后公布(这两天正在忙竞聘)。