DELETE 命令在聚簇索引上花费大量时间

问题描述 投票:0回答:1

我的表中没有大量数据。它仅包含 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)
sql sql-server sql-delete clustered-index non-clustered-index
1个回答
0
投票

要删除的行的标识显示为 3 毫秒。

99.96% 的运行时间显示为聚集索引删除运算符本身占用的时间。

聚簇索引删除运算符还可以在您获得“窄”计划时包括维护非聚簇索引的时间,但这可能负责此时间(就 IO 而言)是不现实的。

看起来它可能只是被阻塞等待获取 X 锁以执行 DELETE。因此,您应该查看阻塞会话是什么,以及是否可以对这些会话进行任何操作以在更短的时间内持有锁(它们是否以比所需的更高的隔离级别运行并且持有

S
不必要的长锁意味着读取部分可以获得
U
锁定但写入部分随后被阻止转换为
X
锁?)。

© www.soinside.com 2019 - 2024. All rights reserved.