GUID似乎是主键的一种自然选择-如果真的需要的话,您可能会争论将它用于表的主键。我强烈建议不做是将guid列用作聚类键,默认情况下,除非您特别告诉它不要这样做,否则SQL Server将执行以下操作。
你真的需要把两个问题分开:这个主键是一个逻辑结构-唯一和可靠地标识表中每一行的候选键之一。这可能是任何东西,真的.INT..GUID,一个字符串-选择对你的场景最有意义的东西。
这个聚类键(定义表上“聚集索引”的一列或多列)-这是一个物理存储相关的东西,在这里,一个小的,稳定的,不断增加的数据类型是你最好的选择-INT或BIGINT作为你的默认选择。
默认情况下,SQLServer表上的主键也用作群集键-但不需要这样做!我亲眼目睹了在将以前基于GUID的主/群集密钥拆分为两个单独的键(GUID上的主(逻辑)键和单独的集群(排序)键)时,性能有了很大的提高。INT IDENTITY(1,1)列。
如金伯利·特里普-索引女王-还有其他人-曾多次指出GUID由于聚类键不是最优的,因为它的随机性会导致大量的页面和索引碎片,并且通常会导致性能较差。
是的,我知道-newsequentialid()在SQLServer 2005和更高版本中-但即使这样也不是真正和完全连续的,因此也存在与GUID-只是不太显眼而已。
然后还有另一个需要考虑的问题:表上的聚类键也将添加到表上每个非聚集索引的每个条目中,因此您确实希望确保它尽可能小。通常,INT对于绝大多数表来说,有超过2万亿行就足够了-并且与GUID作为群集键,您可以在磁盘和服务器内存中节省数百兆字节的存储空间。
快速计算-使用INTv.V.GUID作为主键和群集键:1‘000行的基表(3.8 MB对15.26 MB)
6个非聚集索引(22.89 MB对91.55 MB)
共计:25 MB对106 MB-就在一张桌子上!
更多的思考食物-金伯莉·特里普的优秀作品-读一遍,再读一遍,消化它!这是SQLServer索引的福音,真的。
PS:当然,如果你处理的只是几百或几千行,那么这些争论对你的影响并不大。然而,如果你进入成千上万行,或者你开始数百万-然后这些观点变得非常重要和非常重要的理解。
最新情况:如果你想PKGUID列作为主键(但不是群集键)和另一列。MYINT (INT IDENTITY)作为群集密钥-请使用以下命令:CREATE TABLE dbo.MyTable(PKGUID UNIQUEIDENTIFIER NOT NULL,
MyINT INT IDENTITY(1,1) NOT NULL,
.... add more columns as needed ...... )ALTER TABLE dbo.MyTableADD CONSTRAINT PK_MyTablePRIMARY KEY NONCLUSTERED
(PKGUID)CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)
基本上:你只需要明示告诉PRIMARY KEY约束它是NONCLUSTERED(否则,默认情况下它是作为聚集索引创建的)然后创建第二个索引,定义为CLUSTERED
这将是一个有效的选择,如果你有一个现有的系统,需要“重新设计”的性能。对于一个新系统,如果您从头开始,而不是在复制场景中,那么我总是选择ID INT IDENTITY(1,1)作为我的集群主键-比其他任何东西都高效得多!