当为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。
答案 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。