GUID(全局唯一标识符)可能是作为您的主键的自然选择,如果您真的必须使用它作为表的主键,那么您可能会争辩使用它。但我强烈建议不要使用GUID列作为聚集键,因为SQL Server默认情况下会这样做,除非您明确告诉它不要这样做。
您需要分开考虑两个问题:
1)主键是一个逻辑结构 - 候选键之一,可唯一可靠地标识表中的每一行。这可以是任何东西 - INT、GUID、字符串 - 选择对您的场景最有意义的。
2)聚集键(定义表上“聚集索引”的列)- 这是一个与物理存储相关的东西,在此处,小而稳定的、不断增长的数据类型是您的最佳选择 - 默认选项为INT
或BIGINT
。
默认情况下,SQL Server表上的主键也用作聚集键 - 但这并非必须如此!我个人见过将以GUID为基础的主/聚集键拆分为两个单独键时获得的大量性能提升 - 主(逻辑)键在GUID
上,聚集(排序)键在单独的INT IDENTITY(1,1)
列上。
正如索引女王Kimberly Tripp和其他人多次指出的那样 - 将GUID作为聚集键并不是最佳选择,因为由于其随机性,它将导致大量页面和索引碎片以及通常的性能问题。
是的,我知道 - 在SQL Server 2005及以上版本中有newsequentialid()
- 但即使如此,它也不是真正的完全顺序的,因此还会遇到与GUID相同的问题 - 只是稍微不那么明显。
考虑另一个问题:在表上的聚集键也会添加到每个非聚集索引的每个条目中,因此您确实希望确保它尽可能小。通常,对于绝大多数表来说,使用具有20亿以上行的INT类型将足够 - 与使用GUID作为聚集键相比,您可以在磁盘和服务器内存中节省数百兆字节的存储空间。
快速计算 - 使用INT与GUID作为主键和聚集键:
- 具有1'000'000行的基本表(3.8 MB vs. 15.26 MB)
- 6个非聚集索引(22.89 MB vs. 91.55 MB)
TOTAL: 25 MB vs. 106 MB - 而且这只是单个表的数据!
更多的思考材料 - 由Kimberly Tripp撰写的优秀文章 - 阅读它,阅读它再次消化一下!它真的是SQL Server索引的要义。正如她在"聚集索引辩论继续"一文中所示,拥有良好的聚集键(相对于没有或不良的聚集键)确实可以加速几乎所有数据库操作!这是一个好主意 - 但它必须是一个好的聚集键...
磁盘空间很便宜 - 但这不是重点!
Marc
INT IDENTITY
作为你的聚集键 - 这应该会有很大的改进!但不要完全摆脱你的聚集键 - 一个堆栈甚至更慢... - marc_s