1

我有一个用于物联网数据的相对较大的数据库,大约有 6000 万条记录。插入在流分析的批量插入中非常频繁地执行。

这是我的表架构:

CREATE TABLE [dbo].[NVEControllerReadings](
[DeviceUniqueIdentifier] [nvarchar](100) NOT NULL,
[NVEControllerTimestamp] [datetimeoffset](7) NOT NULL,
[ProcessedInAzureUtc] [datetimeoffset](7) NOT NULL,
[ParameterTypeId] [int] NULL,
[InstanceId] [int] NULL,
[ParameterNumberId] [int] NOT NULL,
[ParameterValue] [float] NULL,
[ParameterText] [nvarchar](255) NULL)

执行查询时,我们总是在寻找设备的最新记录,所以我有以下聚集索引:

CREATE CLUSTERED INDEX [IX_NVEControllerReadings] ON [dbo].[NVEControllerReadings](
[DeviceUniqueIdentifier] ASC,
[NVEControllerTimestamp] DESC)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]

我还有一个非聚集索引,用于覆盖针对 ParameterTypeId、ParameterNumberId 和 InstanceId 的索引。

CREATE NONCLUSTERED INDEX [IX_ParameterTypeId_ParameterNumberId_InstanceId] ON [dbo].[NVEControllerReadings](
[ParameterTypeId] ASC,
[ParameterNumberId] ASC,
[InstanceId] ASC) INCLUDE (     [ParameterValue]) WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]

ParameterValue 作为键列包含在内,因为这是查询的最终结果,我很感兴趣。

但是,在针对我的非聚集索引执行查询时,可能需要 3-5 分钟才能返回一个结果,我不明白。根据我的执行计划,非聚集索引按预期与 Index Seek 一起使用。

这是执行计划的链接: https ://www.brentozar.com/pastetheplan/?id= r1NAwrRUN(查询完成时间为 03:32)。

我尝试重建索引以降低碎片率并更新统计信息,但到目前为止还没有运气。

谁能指出我的问题的方向?

提前致谢。

4

2 回答 2

2

您仍在选择每一行,然后对其进行排序,但它只返回前 1。尝试从另一个方向获取它,使用聚合函数将选择限制为单行,类似于:

SELECT [ParameterValue]
FROM [dbo].[NVEControllerReadings] n1
  join (select max(NVEControllerTimestamp) as Mostrecent, DeviceUniqueIdentifier
        from [dbo].[NVEControllerReadings] 
        WHERE DeviceUniqueIdentifier = '04EFB80706A7'
          AND ParameterTypeId = 19 AND ParameterNumberId = 24
          AND InstanceId = 1
        Group by DeviceUniqueIdentifier) n2 on n2.DeviceUniqueIdentifier = n1.DeviceUniqueIdentifier
     and n1.timestamp = n2.Mostrecent

以我的经验,Azure 的性能可能会受到影响,而且您经常需要在查询上尝试许多不同的排列方式。这是因为在 sql 外部 azure 之下与本地 SQL Server 实例非常不同。例如,您的主键解决方案可能不起作用,因为它没有将数据存储在按物理磁盘上集群顺序排列的页面中。无论如何,希望这会有所帮助!

于 2019-03-07T08:10:18.703 回答
0

对于此查询:

SELECT TOP (1) [ParameterValue]
FROM [dbo].[NVEControllerReadings]
WHERE DeviceUniqueIdentifier = '04EFB80706A7' AND
      ParameterTypeId = 19 AND
      ParameterNumberId = 24 AND
      InstanceId = 1
ORDER BY NVEControllerTimestamp desc;

最佳索引是 on (DeviceUniqueIdentifier, ParameterTypeId, ParameterNumberId, InstanceId, NVEControllerTimestamp desc)。我会先试试这个。

于 2019-03-07T12:15:53.613 回答