【发布时间】:2011-04-01 21:21:48
【问题描述】:
我们有一个旧数据库,它是一个 sql server db(2005 和 2008)。
表中的所有主键都是唯一标识符。
这些表目前没有在它们上创建聚集索引,并且我们在只有 750k 记录的表上遇到了性能问题。这是我第一个使用唯一标识符作为唯一主键的数据库,我从未见过 sql server 的返回数据这么慢。
我不想在唯一标识符上创建聚集索引,因为它们不是连续的,因此在插入数据时会降低应用程序的速度。
我们无法删除用于远程站点记录身份管理目的的唯一标识符。
我曾考虑在表中添加一个大整数标识列,并在该列上创建聚集索引并包括唯一标识符列。
即
int identity - 保持插入速度的第一列 唯一标识符 - 确保应用程序按预期工作。
目标是提高身份查询和联表查询性能。
Q1:这会提高数据库的查询性能还是会减慢它的速度?
Q2:有没有我没有列出的替代方案?
谢谢 皮特
编辑:性能问题在于通过 select 语句快速检索数据,尤其是在将几个“事务性/变化”表连接在一起时。
编辑2:表之间的连接一般都在主键和外键之间,对于有外键的表,它们被包含在非聚集索引中,以提供覆盖范围更大的索引。
这些表都没有其他可以提供良好聚集索引的值。
我更倾向于在每个高负载表上添加一个额外的标识列,然后在聚集索引中包含当前的 Guid PK 列以提供最佳查询性能。
编辑 3: 我估计 80% 的查询是通过数据访问机制单独对主键和外键执行的。通常,我们的数据模型具有延迟加载的对象,这些对象在访问时执行查询,这些查询使用对象 id 和 PK 列。我们有大量用户驱动的数据排除/包含查询,它们使用外键列作为过滤器,基于类型 X 的标准排除以下 id。剩下的 20% 是 Enum (int) 或日期范围列上的 where 子句,系统中很少执行基于文本的查询。
在可能的情况下,我已经添加了覆盖索引来覆盖最繁重的查询,但到目前为止我仍然对性能感到失望。正如 bluefooted 所说,数据被存储为堆。
【问题讨论】:
-
您目前在 uniqueidentifiers 上有一个非聚集索引吗?
-
是的,我们在唯一标识符上有非聚集索引。
-
由于您在该列上至少有一个索引,因此您已经在插入时产生了性能损失。根据表的结构,您可能只是能够删除非聚集索引并切换到聚集索引,而对您当前看到的内容几乎没有影响。
-
我对聚集索引的理解是,数据是按照索引指定的顺序存储的,在非顺序 guid 的情况下,它对插入性能有很大的影响。然而,非集群只是指向不会显着降低插入性能的记录的指针。我将仔细检查这些信息并确保我的理解是正确的。
-
彼得,这不是 100% 正确的。还必须对非聚集索引进行排序(请注意,对于所有这些索引,这是对每个页面进行排序,而不是与同一页面中的其他行相比,每个页面内的行)。确实,通常非聚集索引更窄,因此它们更有效,但是当您插入时,您仍然会在整个地方得到页面拆分。
标签: sql sql-server indexing clustered-index identity-column