【发布时间】:2018-01-13 03:28:28
【问题描述】:
我有一个用于 IOT 指标(时间序列数据)的聚集列存储索引表。它包含超过 10 亿行,结构如下:
CREATE TABLE [dbo].[Data](
[DeviceId] [bigint] NOT NULL,
[MetricId] [smallint] NOT NULL,
[TimeStamp] [datetime2](2) NOT NULL,
[Value] [real] NOT NULL
)
CREATE CLUSTERED INDEX [PK_Data] ON [dbo].[Data] ([TimeStamp],[DeviceId],[MetricId]) --WITH (DROP_EXISTING = ON)
CREATE CLUSTERED COLUMNSTORE INDEX [PK_Data] ON [dbo].[Data] WITH (DROP_EXISTING = ON, MAXDOP = 1, DATA_COMPRESSION = COLUMNSTORE_ARCHIVE)
从 2008 年到现在,有大约 10,000 个不同的 DeviceId 值和时间戳。针对此表的典型查询如下所示:
SET STATISTICS TIME, IO ON
SELECT
[DeviceId]
,[MetricId]
,DATEADD(hh, DATEDIFF(day, '2005-01-01', [TimeStamp]), '2005-01-01') As [Date]
,MIN([Value]) as [Min]
,MAX([Value]) as [Max]
,AVG([Value]) as [Avg]
,SUM([Value]) as [Sum]
,COUNT([Value]) as [Count]
FROM
[dbo].[Data]
WHERE
[DeviceId] = 6077129891325167032
AND [MetricId] = 1000
AND [TimeStamp] BETWEEN '2017-07-01' AND '2017-07-30'
GROUP BY
[DeviceId]
,[MetricId]
,DATEDIFF(day, '2005-01-01', [TimeStamp])
ORDER BY
[DeviceId]
,[MetricId]
,DATEDIFF(day, '2005-01-01', [TimeStamp])
当我执行此查询时,我会得到以下性能指标:
因为目前我认为上述查询的段读取次数过多:
Table 'Data'. Scan count 2, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 5257, lob physical reads 9, lob read-ahead reads 4000.
Table 'Data'. Segment reads 11, segment skipped 764.
我认为这没有得到很好的优化,因为读取了 11 个段以仅检索 10 亿个源行中的 212 个(在分组/聚合之前)
然后我运行 Niko Neugebauer 的出色脚本来验证我们的设置和列存储对齐 https://github.com/NikoNeugebauer/CISL/blob/master/Azure/alignment.sql,我在重建列存储聚集索引后得到了这个结果:
MetricId 和 TimeStamp 列的最佳对齐分数为 100%。我们如何确保 DeviceId 列也很好地对齐?我在初始聚集(行存储)索引中使用了列顺序,这是可以优化的地方吗?
【问题讨论】:
-
请将查询计划也粘贴为 xml
-
如果您使用的是 sql server 2016,请尝试使用 dbcc clonedb 并共享数据库,以便其他人可以重现您所面临的确切场景。如果您不使用 2016,您可以编写我们的表格架构、索引、统计信息并尝试共享脚本
-
@TheGameiswar DBCC CLONEDATABASE 从 SQL Server 2014 SP2 开始可用:)
-
@wBob:great ,谢谢你的信息
-
创建缺失的索引怎么样?
标签: sql-server time-series azure-sql-database columnstore