【发布时间】:2017-10-10 10:18:54
【问题描述】:
我在 SQL Server 2016 Enterprise Edition 上的所有列上都有一个 40m 记录的非内存优化表的非聚集列存储索引。
强制使用列存储索引的查询将执行得更快,但优化器会继续选择使用聚集索引和其他非聚集索引。我有很多可用的 RAM,并且正在对维度模型使用适当的查询。
为什么优化器不选择 columnstoreindex?以及如何鼓励使用它(不使用提示)?
这是一个不使用列存储的示例查询:
SELECT
COUNT(*),
SUM(TradeTurnover),
SUM(TradeVolume)
FROM DWH.FactEquityTrade e
--with (INDEX(FactEquityTradeNonClusteredColumnStoreIndex))
JOIN DWH.DimDate d
ON e.TradeDateId = d.DateId
JOIN DWH.DimInstrument i
ON i.instrumentid = e.instrumentid
WHERE d.DateId >= 20160201
AND i.instrumentid = 2
没有提示需要 7 秒,有提示则需要几分之一秒。 没有提示的查询计划是here。 带有提示的查询计划是here。
列存储索引的创建语句为:
CREATE NONCLUSTERED COLUMNSTORE INDEX [FactEquityTradeNonClusteredColumnStoreIndex] ON [DWH].[FactEquityTrade]
(
[EquityTradeID],
[InstrumentID],
[TradingSysTransNo],
[TradeDateID],
[TradeTimeID],
[TradeTimestamp],
[UTCTradeTimeStamp],
[PublishDateID],
[PublishTimeID],
[PublishedDateTime],
[UTCPublishedDateTime],
[DelayedTradeYN],
[EquityTradeJunkID],
[BrokerID],
[TraderID],
[CurrencyID],
[TradePrice],
[BidPrice],
[OfferPrice],
[TradeVolume],
[TradeTurnover],
[TradeModificationTypeID],
[InColumnStore],
[TradeFileID],
[BatchID],
[CancelBatchID]
)
WHERE ([InColumnStore]=(1))
WITH (DROP_EXISTING = OFF, COMPRESSION_DELAY = 0) ON [PRIMARY]
GO
更新。 Plan using Count(EquityTradeID) instead of Count(*) 和hint included
【问题讨论】:
-
您应该提供实际的执行计划和/或 DDL 以获得有意义的答案。
-
添加查询+计划
-
以后尝试使用粘贴计划或类似的东西。使人们更快/更容易看到它。 brentozar.com/pastetheplan/?id=S1cM-JfxW
-
请提供索引 DDL 语句...
-
@Rory 过滤索引?那么优化器就无法知道它是否可以使用索引,它必须首先查询底层数据。如果将
InColumnStore =1添加到查询中会发生什么?
标签: sql-server indexing query-performance sql-server-2016 columnstore