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

时间:2012-12-10 14:52:23

标签: sql-server tsql optimization indexing foreign-keys

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

我一直在寻找添加外键的区域,并依次索引这些列以提高连接的性能。但是,我们的许多表都加入了一个GUID类型的id,在插入项目时生成,而与其他表中该项目相关联的数据通常包含GUID列item_id

我已经读过,将聚簇索引添加到GUID类型列是一个非常糟糕的决定,因为索引需要不断重建才能生效。但是,我想知道,在上述场景中使用非聚集索引是否有任何不利影响?或者假设它有助于提高性能是否合理?如果需要,我可以提供更多信息。

5 个答案:

答案 0 :(得分:15)

<anytype>上的索引是迄今为止改进连接和单例查找的最佳选择。由于缺乏此索引,查询将始终必须以(通常)糟糕的性能结果端到端地扫描整个表,并且并发耗尽。

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

答案 1 :(得分:2)

两个表现:
- 插入
- 选择

索引应该改进选择

索引会减慢插入速度 如果插入顺序,索引不会碎片 如果插入不按顺序,索引将会碎片化 索引碎片会降低插入和选择的速度 通过维护可以对索引进行碎片整理。

将非聚集索引添加到引用FK的列将有助于连接 由于该列很可能没有被命令,因此GUID是没有损失的。

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

答案 2 :(得分:1)

这通常有助于提升表现。但是您可能希望使用小于100%的fillfactor创建索引,这样不可避免的页面拆分不必经常发生。对指数进行定期维护肯定是一个优势。

答案 3 :(得分:1)

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

在像SQL Azure这样的数据库中,必须有一个聚簇索引。所以你可以使用日期/日期时间字段。不需要创建额外的int-identity / autoincrement列,因为一个团队中的一些开发人员倾向于使用这些和其他GUID。导致应用程序不一致。所以只保留GUID ..完全停止!

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

我得到了微软对非群集主题http://blogs.msdn.com/b/sqlazure/archive/2010/05/05/10007304.aspx

的支持

编辑:支持已经消失(“找不到资源”)

答案 4 :(得分:0)

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

请注意不要添加太多非聚集索引。仅在您需要的地方进行优化。运行探查器以查看哪些查询需要很长时间,并仅优化那些查询。此外,请确保将填充因子设置为<50%的值,除非数据库很少获得任何更新,或者空间是约束。

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