针对索引时Azure SQL查询速度较慢
我有一个相对较大的数据库用于物联网数据,大约有6000万条记录。在流分析的批量插入中,插入非常频繁 这是我的表架构:针对索引时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)
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)的复合键。谢谢:)