我刚刚对Int PK加入Vs Guid PK做了一些测试。
表结构和看起来像这样的记录数:
使用EF4的CRUD操作的性能在两种情况下非常相似。
众所周知,在连接中使用时,Int PK具有更好的性能而不是字符串。 所以INNER JOINS的SQL服务器执行计划完全不同
这是一个执行计划:
据我了解,根据上面的执行计划,Int join具有更好的性能,因为它为Clustered索引扫描占用的资源更少,而且它有两种方式,我是对的吗?
可能有人会详细解释这个执行计划吗?
此示例是否足以表明Int PK在连接中具有更好的性能?
答案 0 :(得分:3)
Kimberly Tripp(索引女王)有一篇关于这个主题的优秀博客文章:
Disk space is cheap.... that's not the point!
她很好地展示了“磁盘空间是否便宜 - 使用GUID而不是INT不会伤害”的论点在很多方面完全是假的。
答案 1 :(得分:2)
我不完全确定我理解你想要达到的目标或从这个测试中找到的东西,但是当我读到你的问题时,这里有一些随机的东西突然出现在我的脑海中......
1)在现实生活中,您可能不会同时加入两个整个表,但是其他列上会有过滤器等,从而减少了记录加入一个或两个表。这将影响哪种类型的连接算法最合适/最有效。
上面的计划是将两个表连接在一起的结果,但如果您要在其他列上过滤一个或两个表,那么优化器可能会使用完全不同的连接类型。
2)加入GUID列时哪种类型的连接最好取决于如何生成guid。如果您加入了很多完全随机的guid(例如使用SQL Server的NewID()或CLR Guid.NewGuid()生成),那么散列连接可能是最佳选择。但是,如果你要加入一小组顺序(newsequentialid()/ UuidCreateSequential()),甚至是相同的guid,那么循环连接通常是最有效的选择。
优化器使用索引统计信息来确定要使用的连接类型,但有时对于具有许多guid连接的复杂查询,可能需要强制使用优化器提示的连接类型。
简而言之,如果您要做的是决定是否应该使用GUID或INT PK,那么更真实的测试是更好的选择。创建与您的用例匹配的表,使用大量有些实际的示例数据填充它们,并执行您预计将要执行的某些类型的查询。将两个虚拟表的全部内容连接在一起并不能真正说明使用Guid键可以看到的I / O影响,或者执行计划对涉及int vs guid键的其他查询的影响。
如果使用Guid键,请考虑生成它们的不同选项,并记住,如果您要加入大量记录,使用顺序guid通常是避免过多页面读取的好方法......
答案 2 :(得分:2)
如果你想一下计算机内部如何比较数值,那就很明显了。
此外,GUID使用4倍的空间,这将产生更多的分页,更差的缓存使用等等。
Marc提到的Kimberly Tripp的帖子证明了这一点。