我的表中没有大量数据。它仅包含 16000 条记录。我想从此表中删除大约 33 条记录,这需要 9-10 秒。下面是我要删除的表和查询的架构。请检查并告诉我原因和解决方法。
我分享执行计划图片也供参考:
架构:
CREATE TABLE [dbo].[Report]
(
[ReportId] [bigint] IDENTITY(1,1) NOT NULL,
[WorkId] [int] NOT NULL,
[GeneratedOn] [datetime2](7) NOT NULL,
[Type] [nvarchar](450) NULL,
[CGuid] [uniqueidentifier] NOT NULL,
[CreatedBy] [nvarchar](max) NULL,
[CreatedDate] [datetime2](7) NOT NULL,
[EGuid] [uniqueidentifier] NOT NULL,
[UpdatedBy] [nvarchar](max) NULL,
[UpdatedDate] [datetime2](7) NOT NULL,
[Document] [nvarchar](max) NULL,
[SessionId] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_Report]
PRIMARY KEY CLUSTERED ([ReportId] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[Report]
ADD DEFAULT (GETUTCDATE()) FOR [CreatedDate]
GO
ALTER TABLE [dbo].[Report]
ADD DEFAULT (GETUTCDATE()) FOR [UpdatedDate]
GO
ALTER TABLE [dbo].[Report]
ADD DEFAULT ('00000000-0000-0000-0000-000000000000') FOR [SessionId]
GO
ALTER TABLE [dbo].[Report] WITH CHECK
ADD CONSTRAINT [FK_Report_Work_WorkId]
FOREIGN KEY([WorkId]) REFERENCES [dbo].[Work] ([WorkId])
GO
ALTER TABLE [dbo].[Report] CHECK CONSTRAINT [FK_Report_Work_WorkId]
GO
查询:
-- This select query is executing faster and completed in 1 second
SELECT r.ReportId
INTO #ReportIds
FROM dbo.Report r
JOIN dbo.Work w ON r.WorkId = w.WorkId AND w.TimePeriodId = 2
WHERE r.[Type] = 'BalanceReport'
-- This delete query is taking 9-10 seconds to delete 33 records.
DELETE r
FROM dbo.Report r
WHERE r.ReportId IN (SELECT ReportId FROM #ReportIds)
要删除的行的标识显示为 3 毫秒。
99.96% 的运行时间显示为聚集索引删除运算符本身占用的时间。
聚簇索引删除运算符还可以在您获得“窄”计划时包括维护非聚簇索引的时间,但这可能负责此时间(就 IO 而言)是不现实的。
看起来它可能只是被阻塞等待获取 X 锁以执行 DELETE。因此,您应该查看阻塞会话是什么,以及是否可以对这些会话进行任何操作以在更短的时间内持有锁(它们是否以比所需的更高的隔离级别运行并且持有
S
不必要的长锁意味着读取部分可以获得U
锁定但写入部分随后被阻止转换为 X
锁?)。