针对索引时Azure SQL查询速度较慢

针对索引时Azure SQL查询速度较慢,sql,sql-server,azure-sql-database,azure-sql-managed-instance,Sql,Sql Server,Azure Sql Database,Azure Sql Managed Instance,我有一个相对较大的数据库用于物联网数据,大约有6000万条记录。在流分析的批量插入中,插入非常频繁 这是我的表架构: CREATE TABLE [dbo].[NVEControllerReadings]( [DeviceUniqueIdentifier] [nvarchar](100) NOT NULL, [NVEControllerTimestamp] [datetimeoffset](7) NOT NULL, [ProcessedInAzureUtc] [datetimeoffset](7)

我有一个相对较大的数据库用于物联网数据,大约有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分钟才能返回一个结果,我不理解这一点。根据我的执行计划,非聚集索引与索引查找一样使用

以下是执行计划的链接: (查询花了03:32完成)

我尝试过重建索引以获得较低的碎片率并更新统计数据,但到目前为止运气不佳

有人能给我指出我的问题所在吗


提前感谢。

您仍在选择每一行,然后对其进行排序,但它只返回前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的本地实例非常不同。例如,您的主键解决方案可能不起作用,因为它不将数据存储在物理磁盘上按群集顺序排列的页面中。无论如何,希望这有帮助

对于此查询:

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

最佳索引位于
(DeviceUniqueIdentifier、ParameterTypeId、ParameterNumberId、InstanceId、InveControllerItemStamp desc)
。我会先尝试一下。

我的第一个想法是:对于必须存储的数据,您使用了错误的数据存储类型。举个例子,这是有道理的。从聚集索引中排除时间戳,并将其作为DESC包含在非聚集索引中,这是一个更好的主意吗?这可能是最好的主意。我的聚集索引(DeviceId,NVeControllerItemStamp)如何?当我现在有一个包含这些键的非聚集索引时,是否应该更改此设置?@Mortenkp25。你需要一个包含
WHERE
(至少)中所有四列的索引,然后是排序列。我发现这实际上是一个碎片问题。重建索引后,它们很快又变得支离破碎。我将尝试引入一个标识列,并将聚集索引重新设计为(DeviceUniqueIdentifer,Id)的复合键。谢谢:)