在SQL Server中对guid类型列使用非聚集索引



我想优化我的团队用于应用程序的数据库的性能。

我一直在寻找添加外键的区域,然后对这些列进行索引,以提高联接的性能。然而,我们的许多表是在一个GUID类型的id上联接的,该id是在插入一个项时生成的,而其他表中与该项相关联的数据通常具有包含GUID的列item_id

我读到过向GUID类型的列添加聚集索引是一个非常糟糕的决定,因为索引需要不断重建才能有效。然而,我想知道,在上述场景中使用非聚集索引是否有任何损害?还是可以合理地认为这将有助于绩效?如果需要,我可以提供更多信息。

<anytype>上的索引是迄今为止改进联接和单例查找的最佳选项。如果没有这个索引,查询总是必须端到端地扫描整个表,结果(通常)非常糟糕,并发性也会耗尽。

确实,由于您提到的原因,uniqueidentifier对索引的选择很差,但这并不意味着您应该而不是创建这些索引。如果可能的话,建议将数据类型更改为INT或BIGINT。使用NEWSEQUENTIALID()UuidCreateSequential生成它们将有助于解决碎片问题。如果所有备选方案都失败了,您可能需要比其他索引更频繁地执行索引维护(重建、重组)操作但这些缺点决不会超过将索引放在首位的好处

两种性能:
-插入
-选择

索引应改进选择

索引会减慢插入速度
如果插入顺序正确,则索引不会分段
如果插入顺序不正确,则索引将分段
索引碎片会减慢插入和选择的速度
通过维护可以对索引进行碎片整理。

向引用FK的列添加非聚集索引将有助于联接
由于该列很可能没有排序,因此它是GUID这一事实不会丢失。

在FK表本身上,GUID不是PK(聚集索引)的好候选者
使用GUID作为插入时索引片段的PK
Int或sequence ID是更好的候选者,因为它们不会在插入时分割PK
但没什么大不了的,只是对那些表进行碎片整理。

是的,最好将Guid索引从集群更改为非集群。Guid仍然可以是主键,您不需要更改查询/源代码。无需重新排序数据并提高性能。

在像SQL Azure这样的数据库中,必须具有聚集索引。因此,您可以使用日期/日期时间字段。创建额外的int identity/autoincrement列是不必要的,因为一个团队中的一些开发人员倾向于使用这些和其他GUID。导致应用程序不一致。所以只保留GUID。。句点

谈到顺序Guid,我认为从代码创建Guid比从数据库创建Guid更好。现代的DAL和存储库模式不喜欢CRUD依赖DB。例如,场景:linq查询和带有单元测试的自动化构建,不依赖DB。并且自己创建一个连续的guid不是一个好主意(至少对我来说)。所以Guid作为非聚集索引的主键是最好的选择

我在非群集主题上得到了Microsoft的支持http://blogs.msdn.com/b/sqlazure/archive/2010/05/05/10007304.aspx

已编辑:备份已消失("找不到资源")

这通常有助于提高性能。但您可能希望创建填充因子小于100%的索引,这样不可避免的页面拆分就不必经常发生。定期维护指数当然是一个加分项。

是的,非聚集索引非常适合您的情况。底层是B树,就像聚集索引一样,但表上的底层数据没有排序,因此GUID的非顺序性问题不存在。NC索引与表分开存在。

不过,请注意不要添加太多非聚集索引。只在需要的地方进行优化。运行探查器查看哪些查询需要很长时间,然后只优化那些查询。此外,确保将填充因子设置为<50%,除非数据库很少得到任何更新,或者空间是一个限制。

相关MSDN:http://msdn.microsoft.com/en-us/library/ms177484(v=sql.105).aspx

最新更新