与这里的大多数人所宣扬的相反,我认为 GUID 不是一种神器而是一种灾难。以下是原因:
GUID 看起来似乎是作为主键的自然选择——如果您确实需要,可能可以争辩使用它作为表的 PRIMARY KEY。但我强烈建议不要将 GUID 列用作聚集键(clustering key),这是 SQL Server 的默认设置,除非您明确告诉它不要这样做。
您真的需要将两个问题分开:
主键(primary key)是一个逻辑构造——唯一可靠地标识表中每一行的候选键之一。这可以是任何东西——一个 INT,一个 GUID,一个字符串——选择对您的情况最有意义的。
聚集键(clustering key)(定义表上的"聚集索引(clustered index)"的列)——这是与物理存储相关的事情,在这里,稳定且不断增长的数据类型是最好的选择——INT或BIGINT作为默认选项。
默认情况下,SQL Server 表上的主键也被用作聚集键——但不必如此!我亲自看到了当将以 GUID 为基础的 Primary/Clustered Key 分成两个单独的键时,性能显著提高——主键(逻辑)在 GUID 上,而聚集(排序)键在一个单独的 INT IDENTITY(1,1) 列上。
正如索引女王Kimberly Tripp和其他人多次指出的那样,GUID 作为聚集键并不是最佳选择,因为由于其随机性,它将导致大量页面和索引碎片化以及通常的糟糕性能。
是的,我知道——在 SQL Server 2005 及更高版本中有 newsequentialid()
,但即使如此,它也不是真正和完全的顺序的,因此也会遇到 GUID 相同的问题,只是稍微不那么明显而已。此外,您只能将其用作表中列的默认值,无法在 T-SQL 代码(如触发器之类)中获取新的连续 GUID——这是另一个主要缺点。
然后还有另一个问题需要考虑:表上的聚集键还将添加到每个非聚集索引上的每个条目中——因此,您确实希望确保它尽可能小。通常,具有 20 多亿行的 INT 对于绝大多数表来说应该足够了——与作为聚集键的 GUID 相比,您可以在磁盘和服务器内存上节省数百兆字节的存储空间。
快速计算——使用 INT 与 GUID 作为主键和聚集键:
- 基本表格具有 1,000,000 行(3.8 MB vs. 15.26 MB)
- 6 个非聚集索引(22.89 MB vs. 91.55 MB)
总计:25 MB vs. 106 MB ——仅仅是单个表格!
还有一些关于此的值得考虑的东西——Kimberly Tripp 提供的绝妙内容——阅读它,再次阅读它,领会它!这是 SQL Server 索引福音的真谛。
越来越大的聚集键 - 聚集索引辩论...... 再次发生!
马克