gpt4 book ai didi

sql-server - 为什么不使用列存储索引

转载 作者:行者123 更新时间:2023-12-02 10:23:33 28 4
gpt4 key购买 nike

我在 SQL Server 2016 Enterprise Edition 上的 40m 记录非内存优化表的所有列上都有一个非聚集列存储索引。

强制使用列存储索引的查询执行速度会明显加快,但优化器会继续选择使用聚集索引和其他非聚集索引。我有大量可用 RAM,并且正在对维度模型使用适当的查询。

为什么优化器不选择列存储索引?我怎样才能鼓励它的使用(不使用提示)?

以下是不使用列存储的示例查询:

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

最佳答案

您要求 SQL Server 选择一种复杂的查询计划而不是简单的查询计划。请注意,使用提示时,SQL Server 必须将列存储索引与行存储非聚集索引 (IX_FactEquiteTradeInColumnStore) 连接起来。仅使用行存储索引时,它可以执行查找(我假设 TradeDateId 是该索引的前导列)。它确实仍然需要进行键查找,但它更简单。

我可以看到两个选项可以在没有提示的情况下实现此行为:

首先,从列存储索引定义中删除 InColumnStore 并覆盖整个表。这就是您对列存储的要求 - 涵盖所有内容。

如果不可能,您可以使用 UNION ALL 显式拆分数据:

WITH workaround
AS (
SELECT TradeDateId
, instrumentid
, TradeTurnover
, TradeVolume
FROM DWH.FactEquityTrade
WHERE InColumnStore = 1
UNION ALL
SELECT TradeDateId
, instrumentid
, TradeTurnover
, TradeVolume
FROM DWH.FactEquityTrade
WHERE InColumnStore = 0 -- Assuming this is a non-nullable BIT
)
SELECT COUNT(*)
, SUM(TradeTurnover)
, SUM(TradeVolume)
FROM workaround e
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;

关于sql-server - 为什么不使用列存储索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43914966/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com