我有一张包含近 600 万条记录的表。标识唯一行的业务键非常大。自从我为新多维数据集添加这个新表以来,我们的更新处理现在花费了更长的时间。我目前在更新的连接列上没有索引。SQL Server 估计执行计划说我应该在业务键上创建这个索引:
/*
Missing Index Details from Server.db
The Query Processor estimates that implementing the following index
could improve the query cost by 86.9178%.
*/
/*
USE [db]
GO
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [schema].[Production]
(
[ProdId],[PriceCalc],[CalcTypeId],[OprId],[CostGroupId],[Resource],
[BOM],[ResourceDepartment],[OprNum],[DateWIP],[DataAreaId],[Partition]
)
INCLUDE
(
[ProdOrderStatus],[ManufacturedItemId],[CalcType],[CalculationLevel],
[CostAnalysisOrderType],[CostGrouping],[UnitId],[WorkCenter],[Name],
[RealisedConsumption],[RealisedCostAmount],[RealisedCostAdjustment],
[EstimatedConsumption],[EstimatedCostAmount],[LotSizeVariance],
[StandardQty],[StandardCost],[ItemStandardQty],[HasSubstitutionVariance],
[R2],[R3],[StandardQtyByRAFQty],[StandardCostByRAFQty],[ProductionOrderType],
[RealisedAllocation],[CostVariance],[QuantityVariance],[SubstitutionVariance],
[TotalVariance],[ComponentItemId],[InventoryUOM],[InventConsumptionTransUOM],
[BomConsumptionTranUOM],[TransactionUOM],[TransUOMToInvUOMConversionRate],
[InventConsumptionInvUOM],[BomConsumptionInvUOM],[TotalNetWeightPerUnitInvUOM],
[InventoryNetWeightUOM],[ReportingNetWeightUOM],
[NetWeight_InvUOMToReportingUOMConversionRate],
[InventConsumptionTotalNetWeightInvUOM],[BomConsumptionTotalNetWeightInvUOM],
[InventConsumptionTotalNetWeightReportingUOM],
[BomConsumptionTotalNetWeightReportingUOM],
[FinancialProductId],[FinancialDepartmentId],[FinancialMarketId],[FinancialCodeId],
[FinancialTypeId],[FinancialSiteId],[ProdPoolId],[Company_SK],[ComponentItem_SK],
[EndedDate_SK],[DateWIP_SK],[FinancialCode_SK],[FinancialDepartment_SK],
[FinancialMarket_SK],[FinancialProduct_SK],[FinancialSite_SK],[FinancialType_SK],
[InventoryNetWeightUOM_SK],[InventoryUOM_SK],[ManufacturedItem_SK],
[ProductionOrder_SK],
[ReportingNetWeightUOM_SK],[TransactionUOM_SK],[BatchRunId],[ValidInd],[ScrapVar],
[QuantityPO],[ExpectedConsumption],[FibreScrapFactor],[QtyAndSubVariance],
[EndedDate],[RealisedAllocationCost],[FilmScrapFactor])
GO
*/
它想在键列上创建一个索引,但是它想包含很多列。我应该听还是只包含关键列?谢谢你的帮助。这是一个生产问题,所以我不能去测试不同的东西等。
我们正在考虑按照以下思路引入哈希解决方案:
使用 Hashbytes 跟踪和存储 SQL Server 数据的历史变化
短期来看,下周是重要的金融收尾期,系统需要良好运行,加指数似乎是个好主意。所以我想尽快做任何我能做的事。您会推荐用于长期/新实施的哈希解决方案吗?
我正在假设所讨论的表是事实表,而不是具有巨大复合键的维度表:
只是为了在短期内解决性能问题,我会将所有这些键列添加为表的聚集索引,这意味着您不必
INCLUDE
像建议的索引那样采取很多措施和措施。此外,如果数据允许,请使索引唯一。至于事实表上聚集索引的列顺序,这取决于您访问它们的方式。如果您只使用多维数据集来读取大块数据,我可能会
INSERT
通过按时间顺序排列索引来确定优先级,即将日期列放在第一位 - 这样,新行就会添加到索引的末尾(最好的世界)。如果您在事实表上运行用户 T-SQL 查询,我会尝试按照尽可能多地为您提供索引搜索或范围扫描的顺序排列索引列:首先,在单个维度键上过滤的列(想想“年”、“类型”、“单位”或“部门”类型的维度),然后是那些在多个维度成员、范围上过滤或用于排序的列。
当然,还有其他学校关于如何建立索引——这不是“单一正确答案”。
编辑:关于聚簇索引与非聚簇索引的更多信息:
我猜你已经有了一个聚集索引,这就是 SQL Server 建议使用非聚集索引的原因。但是,非聚集索引必须用
INCLUDE
列显式定义。聚簇索引定义了表的实际存储/排序顺序,因此,它们将隐含地包含表中的所有列(我不会讨论像 varchar(max) 和 xml 这样的 LOB 列)。聚集索引通常是“包罗万象的索引”,它负责处理不适合现有非聚集索引的查询,这使得它(在我看来)设计良好而不是更加重要,因为例如,就在一
IDENTITY()
列上。此外,非聚集索引将占用更多的驱动器空间,因此覆盖表所有列的非聚集索引实际上将占用与表本身一样多的空间。聚簇索引就是表。