这些指数是否相互排斥?

时间:2013-07-16 12:04:02

标签: sql-server

我有一个SQL 2008数据库正在尝试调整,我已经使用了一些我从SQL数据管理视图中生成推荐索引的示例。

在某些情况下,我看到推荐了多个索引,这些索引在INCLUDE部分之前具有相同的定义,此时它们有一些不同的列用于骑行。

我知道我不应该只创建来自互联网的脚本所建议的每个索引,但除此之外,如果我确实创建了所有这些索引,引擎是否会根据需要使用这些索引,或者其中两个没用?

CREATE INDEX [IX_FactBilling_FiscalPeriodKey1]
  ON [ClearViewDev].[Performance].[FactBilling] ([fiscalperiodkey])
  include ([TotalReceived], [ExchangeRateTimeKey], [MatterKey], [BillingTypeKey]
, [CurrencyKey], [PersonKey], [CompanyKey], [OfficeKey], [PracticeGroupKey],
[ProfitCenterKey], [PersonnelTypeKey], [RankKey])

CREATE INDEX [IX_FactBilling_FiscalPeriodKey2]
  ON [ClearViewDev].[Performance].[FactBilling] ([fiscalperiodkey])
  include ([TotalBilled], [ExchangeRateTimeKey], [MatterKey], [BillingTypeKey],
[CurrencyKey], [PersonKey], [CompanyKey], [OfficeKey], [PracticeGroupKey],
[ProfitCenterKey], [PersonnelTypeKey], [RankKey])

CREATE INDEX [IX_FactBilling_FiscalPeriodKey3]
  ON [ClearViewDev].[Performance].[FactBilling] ([fiscalperiodkey])
  include ([TotalBilled], [TotalReceived], [MatterKey], [BillingTypeKey],
[TransactionDateKey], [BusinessProcessInstanceDateKey], [PersonKey],
[CompanyKey], [OfficeKey], [PracticeGroupKey], [ProfitCenterKey],
[PersonnelTypeKey], [RankKey], [BillableHoursBilled], [BillableValueBilled],
[StandardValueBilled], [HoursBilled])  

1 个答案:

答案 0 :(得分:3)

严格回答这个问题:

  1. TotalReceived,ExchangeRateTimeKey,MatterKey,BillingTypeKey,CurrencyKey,PersonKey,CompanyKey,OfficeKey,PracticeGroupKey,ProfitCenterKey,PersonnelTypeKey,RankKey

  2. TotalBilled,ExchangeRateTimeKey,MatterKey,BillingTypeKey,CurrencyKey,PersonKey,CompanyKey,OfficeKey,PracticeGroupKey,ProfitCenterKey,PersonnelTypeKey,RankKey

  3. TotalBilled,TotalReceived,MatterKey,BillingTypeKey,TransactionDateKey,BusinessProcessInstanceDateKey,PersonKey,CompanyKey,OfficeKey,PracticeGroupKey,ProfitCenterKey,PersonnelTypeKey,RankKey,BillableHoursBilled,BillableValueBilled,StandardValueBilled,HoursBilled

  4. 除第一个字段(TotalReceived vs TotalBilled)外,索引1和2相同。索引3与1和2不同。理论上,索引2不包含需要TotalBilled的查询,索引1不包含需要TotalReceive的查询。但这些都是理论上的。

    没有人会考虑添加这3个指数。他们太宽了。优化器向您暗示的是,它真的非常希望FiscalPeriodKey成为聚簇索引中最左侧的键。在时间序列中,群集密钥的最佳选择是时间密钥,因为时间序列通常是针对时间范围查询的。唉,对于DW事实表,时间只是查询维度的一个,通常其他维度(例如地理,组织单位,产品系列)也用于查询。而且你只能选择一个作为集群密钥。将覆盖索引方法推向极限以覆盖所有这些情况会导致巨大的数据大小膨胀和较差的写入性能。最终,您面临着意识到您正在使用错误的工具。

    我建议您调查升级到columnstores。所有这些问题都将消失,因为柱状存储使用完全不同的方法,并且查询受益于segment elimination。当然,这个 至少需要SQL Server 2012,并推荐updatable columnstores的SQL Server 2014。

    更可口的解决方案是咬紧牙关并部署SSAS多维数据集。 MOLAP在这些问题中猖獗,而关系服务器根本没有答案(至少在列存储之前没有)。

      

    没有群集密钥。 “ID”是主键

    我将假设您的意思是“ID是用作主键的标识,默认情况下是群集密钥”。如果你的意思是你的堆有一个非聚集的主键ID那么......你应该得到你遇到的问题而且更糟糕。

    您所面临的问题的常见解决方法(在'index tipping point'的绰号下在业内众所周知)是利用ID和插入时间之间的关联。存储特定时间范围的最小和最大ID的旁视表用于限制聚簇索引扫描。有关具体示例,请参阅Disposable Indexes。但是,相关性仅存在于一个维度(时间),而不存在于其他DW维度中,因此您回到与选择聚簇索引时间键相同的问题。同样,SSAS多维数据集或列存储更适合该任务。