关于侯垒的自增字段和GUID字段性能对比文章的一些自己的分析(没有测试,纯粹分析)
一上午都在忙着面试,闲暇看到侯垒的文章,http://www.cnblogs.com/houleixx/archive/2009/07/29/SQL-id-guid.html,我觉得他为一个很小的细节作出这么多的测试,实在是佩服,但是基于我自己的一些知识,可能有些东西不是很认可。
mssql的int自增是4字节,GUID是4个4字节,根据mac地址产生分有序列和无序列,有序列即产生的GUID自增,无序列产生的GUID随机大小。仅凭这一点,在mssql在构造B树的时候,一个8KB的索引页能存储的int索引是GUID的四倍,也就是说采用GUID的索引树IO大小是int类型索引的4倍,这个是理论值,还存在页间裂缝碎片等,比理论值还要高。可以想象一个测试案例:一棵聚集B树,1000w的id,如果是int那么粗略估计是使用1000w×4/8000=5000个叶级页面,如果是GUID是1000w×16/8000=2w个页级页面,如果是fullscan,那么IO就很容易对比出来哪个速度快。如果是lookup,树的高度肯定也是GUID的高,但是IO优势体现不明显,除非大量的lookup。另外,如果是类似id>1000,那性能差距更夸张,不过似乎采用GUID的话,就不好比大小了。不过有个应用场景对GUID是致命的,也就是经常的应用场景需要用ID去跟其他表关联查找,这个时候,性能的差异就完全暴露,但是侯磊在测试中完全没有顾及。如果是关联查找,无论哪个表作为内表,其关联字段都需要做排序索引,如果没有排序,那么就需要先在内存中排序,或者使用hashjoin,但是这个方式是非常耗费CPU的,所以大小表的关联最佳采用是嵌套,综上,使用GUID在各个应用场景上都与int类型没有什么优势可言,希望大家啊探讨,或者写个测试脚本试试,看看执行计划和IO对比。
mssql的int自增是4字节,GUID是4个4字节,根据mac地址产生分有序列和无序列,有序列即产生的GUID自增,无序列产生的GUID随机大小。仅凭这一点,在mssql在构造B树的时候,一个8KB的索引页能存储的int索引是GUID的四倍,也就是说采用GUID的索引树IO大小是int类型索引的4倍,这个是理论值,还存在页间裂缝碎片等,比理论值还要高。可以想象一个测试案例:一棵聚集B树,1000w的id,如果是int那么粗略估计是使用1000w×4/8000=5000个叶级页面,如果是GUID是1000w×16/8000=2w个页级页面,如果是fullscan,那么IO就很容易对比出来哪个速度快。如果是lookup,树的高度肯定也是GUID的高,但是IO优势体现不明显,除非大量的lookup。另外,如果是类似id>1000,那性能差距更夸张,不过似乎采用GUID的话,就不好比大小了。不过有个应用场景对GUID是致命的,也就是经常的应用场景需要用ID去跟其他表关联查找,这个时候,性能的差异就完全暴露,但是侯磊在测试中完全没有顾及。如果是关联查找,无论哪个表作为内表,其关联字段都需要做排序索引,如果没有排序,那么就需要先在内存中排序,或者使用hashjoin,但是这个方式是非常耗费CPU的,所以大小表的关联最佳采用是嵌套,综上,使用GUID在各个应用场景上都与int类型没有什么优势可言,希望大家啊探讨,或者写个测试脚本试试,看看执行计划和IO对比。