Eu tenho uma consulta que faz uma varredura de índice clusterizado em uma tabela muito grande, a varredura está causando tempos limite em alguns cenários. Precisa de ajuda para entender por que não está usando os índices não clusterizados definidos.
Aqui está a consulta:
DECLARE @StartDate datetime = '2023-03-16 00:00:00';
DECLARE @TerminalIds [dbo].[udtBigInt]; -- user defined table with a BIGINT col
INSERT INTO @TerminalIds ([Id])
SELECT [EquipmentId]
FROM #mechanicsTerminal;
SELECT [DataRecId]
, [RawData]
, [RecordingTime]
, [EquipmentId]
FROM [dbo].[Data]
WHERE [EquipmentId] IN (SELECT [Id] FROM @TerminalIds)
AND [RecordingTime] >= @StartDate
ORDER BY [DataRecId] DESC
OFFSET 0 ROWS FETCH NEXT 50 ROWS ONLY;
Aqui está a definição da tabela:
CREATE TABLE [dbo].[Data](
[DataRecId] [bigint] IDENTITY(1,1) NOT NULL,
[RawData] [nvarchar](max) NOT NULL,
[CreatedDateUTC] [datetime] NOT NULL,
[RecordingTime] [datetime] NOT NULL,
[EquipmentId] [bigint] NOT NULL,
[DataSetId] [uniqueidentifier] NULL,
[SourceType] [nvarchar](50) NULL,
[Name] [nvarchar](100) NULL,
PRIMARY KEY CLUSTERED ( DataRecId] ASC)
GO
ALTER TABLE [EJ].[Data] WITH CHECK ADD CONSTRAINT [chk_Data_RawData] CHECK ((isjson([RawData])=(1)))
GO
Aqui estão os índices:
CREATE INDEX [nc_Data_DataSetId_includes]
ON [dbo].[Data] ( [DataSetId] ) INCLUDE ( [DataRecId], [RawData], [RecordingTime]);
GO
CREATE INDEX [nc_Data_EquipmentId_includes]
ON [dbo].[Data] ( [EquipmentId] ) INCLUDE ( [DataSetId], [RawData]);
GO
CREATE INDEX [nc_Data_EquipmentId_RecordingTime_Name_includes]
ON [dbo].[Data] ( [EquipmentId], [RecordingTime], [Name] ) INCLUDE ( [DataRecId], [RawData]);
GO
Aqui está o plano de execução real:
https://www.brentozar.com/pastetheplan/?id=B1oq7TDD3
Com esses dados específicos, a consulta é executada em subsegundos.
No entanto, há um cenário em que há apenas três registros em @TerminalIds
, mas nenhum registro correspondente em [dbo].[Data]
, a consulta nunca é concluída. Aqui está o plano após 45 segundos.
https://www.brentozar.com/pastetheplan/?id=rJJMRavDn
O que eu tentei:
- Atualizando estatísticas e recompilando o proc principal
- Fazendo
INNER JOIN
em@TerminalIds
vez de fazer subconsulta comIN
cláusula