guid主键创建最快的查询选择guid in(guid1,guid2,guid3 ...)

时间:2009-06-01 06:47:13

标签: sql-server-2005

需要使用GUID作为主键。我是否正确地认为

ProductID UNIQUEIDENTIFIER NOT NULL 
ROWGUIDCOL DEFAULT (NEWSEQUNTIALID()) PRIMARY KEY CLUSTERED 

将为where子句

提供最快的选择

productid in ( guid1 , guid2 ,..., guidn )

并且不会恶化非群集

natural_key like 'Something*'

独立选择。用于仅由用户查询并从头开始以编程方式创建/重新创建的表。

3 个答案:

答案 0 :(得分:3)

您使用GUID作为聚集索引这一事实肯定会对您的性能产​​生负面影响。即使使用NEWSEQUENTIALGUID,GUID也不是真正的顺序 - 它们只是部分如此。它们的随机性本质上肯定会导致更高的索引碎片,从而导致寻求时间不那么理想。

此外,如果您有一个16字节的GUID作为您的群集密钥,它将被添加到该表上的任何非聚集索引。这可能听起来不是那么糟糕,但如果你有10兆。行,10个非聚集索引,使用16字节GUID与4字节INT将耗费1.2 GByte浪费 - 而不仅仅是在磁盘上(这是便宜的),而且还在SQL服务器的内存中(从那以后) SQL服务器总是将整个8k页加载到8k块内存中,无论它们有多满或多空。)

我可以看到使用GUID作为主键的意义 - 它们几乎100%保证是独一无二的,这对开发人员很有吸引力。但是:作为群集密钥,它们对您的数据库来说是一场噩梦。

我的最佳实践:如果我真的需要一个GUID作为主键,我会在表中添加一个4字节的INT IDENTITY,然后用作聚簇键 - 结果就更好了!

如果您有非群集主键,那么使用GUID列表的查询将与群集主键的查询一样快,并且不使用群集键的GUID,您的表将在结束。

阅读有关群集密钥的更多内容以及为什么在Kimberly Tripps的博客中选择正确的密钥非常重要 - 索引女王并且可以比我更好地解释事情:

马克

答案 1 :(得分:1)

除了GUID是坏的(从marc_s回答),你还有一个IN子句。这可以归结为:

productid = guid1 OR productid = guid2 OR ... OR productid = guidn

......在实践中,这也不是最佳的。

通常,natural_key like 'Something%'很可能更适合您的自然键列上的聚簇索引。

答案 2 :(得分:0)

聚集索引最适合范围搜索,因此它可能满足您的查询:

productid in ( guid1 , guid2 ,..., guidn )

但取决于您选择的其他内容,分组依据,等等,如果索引是覆盖索引。否则,优化器可能会选择另一个非聚集索引,然后查找聚簇索引。它在某种程度上还取决于该表中的行数。

另外,我认为你可能想要使用NEWID()作为反对NEWSEQUENTIALID()