SQL中的索引速度

时间:2009-09-09 02:13:14

标签: sql sql-server sql-server-2005 tsql

当为SQL表创建索引时,如果我在表中有2列的索引并且我将索引更改为表中的4列,那么合理增加节省的时间就会增加100万要期待的行?

我知道这个问题的答案会因许多因素而异,例如外键,其他索引等,但我想我还是会问。不确定是否重要,但我使用的是MS SQLServer 2005。


编辑:好的,所以这里有更多可能有助于获得更好答案的信息。我有一个名为CostDependency的表。此表中包含以下列:

CostDependancyID as UniqueIdentifier (PK)
ParentPriceID as UniqueIdentifier (FK)
DependantPriceID as UniqueIdentifier (FK)
LocationID as UniqueIdentifier (FK)
DistributionID as UniqueIdentifier (FK)
IsValid as Bit

目前有一个唯一索引涉及ParentPriceID,DependantPriceID,LocationID和DistributionID。 此索引的原因是为了保证这四列的组合是唯一的。我们没有在这四个列上进行任何搜索。但我可以对此表进行规范化并将其分为三个表:

CostDependancyID as UniqueIdentifier (PK)
ParentPriceID as UniqueIdentifier (FK)
DependantPriceID as UniqueIdentifier (FK)

Unique Index on ParentPriceID and DependantPriceID

ExtensionID as UniqueIdentifier (PK)
CostDependencyID (FK)
DistributionID as UniqueIdentifier (FK)

Unique Index on CostDependencyID and DistributionID 

ID as UniqueIdentifier (PK)
ExtensionID as UniqueIdentifier (FK)
LocationID as UniqueIdentifier (FK)
IsValid as Bit

Unique Index on ExtensionID and LocationID 

我正在尝试对这个表进行规范化,从而减少索引中的列数意味着在添加大量行(即100万)时速度会有所提高。


谢谢,Dane。

4 个答案:

答案 0 :(得分:1)

这在很大程度上取决于更宽的索引是否构成了查询的覆盖索引(并且在较小程度上构成了该表上读取与写入的比率)。建议您发布您正在尝试改进的查询工作负载的执行计划。

答案 1 :(得分:1)

我对你的目标感到有点困惑。 (编辑后)问题显示您正在尝试优化数据(行)插入,将一列六列和一列四列复合主键与一个“标准化”三元组进行比较每个表有三列或四列,三个表中都有两列复合键。这是你的问题吗?

我的第一个问题是,从一个表到三个表的“规范化”有什么影响?如果单个表中有1M行,那么您在三个规范化的行中可能有多少行?规范化通常会删除冗余数据,这是否会这样做?

将1M行插入四列PK表将花费更多时间,而不是两列PK表 - 可能是一点点,也许很多(参见下一段)。但是,如果所有其他条件都相同,我相信将1M行插入三个双列PK表将比四列一列慢。需要进行测试。

有一点可以肯定的是,如果要插入的数据的加载顺序与存储的数据相同,则比插入的数据已经排序的速度慢很多。将它乘以三,你确实会有很长的等待时间。此问题最常见的解决方法是删除索引,加载数据,然后重新创建索引(听起来像浪费时间,但对于大型数据集,它可能比插入索引表更快)。更抽象的解决方法是将表加载到未编制索引的分区中,(重新)构建索引,然后将分区切换到“实时”表。这是您可以考虑的选项吗?

总的来说,人们在插入数据时并不过分关注性能 - 通常他们会对数据检索性能感到不满。如果不是仓库情况,我有兴趣知道为什么插入性能是你明显的瓶颈。

答案 2 :(得分:1)

有了所有新信息,我想建议以下内容:

1)如果一些GUID(UniqueIdentifier)列是这样的:a)相对较少的不同值,b)在初始加载后添加的新值相对较少。 (例如,LocationID可能代表商店,如果我们每天只看到一些新商店),将这些商店分拆到单独的查找表GUID - > LocalId (INT或一些小列),并在主表中使用此LocalId。 ==>这样做会大大减少主表及其相关索引的总体大小,但代价是稍微复杂化更新逻辑(但不是其性能),因为查找和维护查找表的需要( s)有新的价值观。

2)除非特定的重要/频繁搜索案例能够[好]使用聚簇索引,否则我们可以使用主表上的聚簇索引作为基于4列的唯一复合键。这样可以避免在单独的非聚集索引中复制那么多数据,并且看起来很直观,它可以节省初始加载和新插入的时间。诀窍是使用相对较低的填充因子,以便节点分裂和平衡等很少。顺便说一句,如果我们使用本地ID使主记录更窄,我们可以更容易地在fillfactor中提供“浪费”空间,在需要节点平衡之前,更多的新记录将适合这个空间。

3)link664可以为“主”表中的记录总数提供一个数量级,并且每当/每周/每次预定更新时提供。并且这两个参数可以确认上述方法的有效性,并提供关于在大批量插入之前可能丢弃索引(或其中一些)的可能性,如Philip Kelley所建议的那样。但是,这样做将取决于操作方面的考虑因素,例如在插入新数据时需要继续搜索服务。

4)其他考虑因素,如SQL分区,存储架构等,也可用于改善负载和/或检索性能。

答案 3 :(得分:0)

查询优化器将查看索引并确定它是否可以使用前导列。如果第一列不在查询中,那么它将不会被使用。如果可以使用索引,那么它将检查是否可以使用第二列。如果您的查询包含'其中A =?和C =?'并且您的索引位于A,B,C,D上,那么查询计划中只会使用“A”列。

向索引添加列有时可以避免数据库必须从索引页转到数据页。如果您查询是'从表中选择D,其中a =?和b =?并且c =?',然后将从索引返回列'D',并在必须转到数据页面时节省一些IO。