我有一个对非常大的表执行聚簇索引扫描的查询,该扫描在某些情况下会导致超时。需要帮助理解为什么它不使用定义的非聚集索引。
这是查询:
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;
这是表定义:
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
以下是索引:
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
这是实际的执行计划:
https://www.brentozar.com/pastetheplan/?id=B1oq7TDD3
使用此特定数据,查询将在亚秒级执行。
然而,有一种情况是 中只有三个记录@TerminalIds
,而 中没有匹配的记录[dbo].[Data]
,查询永远不会完成。这是 45 秒后的计划。
https://www.brentozar.com/pastetheplan/?id=rJJMRavDn
我试过的:
- 更新统计数据并重新编译主过程
- 继续而不是用子句做子
INNER JOIN
查询@TerminalIds
IN