谜团:在SQL表中慢速删除

时间:2013-12-15 20:06:18

标签: sql sql-server tsql sql-server-2012 query-optimization

我有一个包含29列和3000-4000行的SQL表。它有一些空间领域(2几何和1地理),但没有什么特别的。

在生产和开发环境中,从此表中删除单行现在大约需要1000毫秒。

Delete from AdminDivisions 
where AdminDivisionID=(Select top 1 AdminDivisionID from AdminDivisions)

screenshot 1

这是我尝试过的(在开发环境中):

  • 我已经对表进行了克隆,并精心重新创建了所有触发器,外键,约束和索引。从克隆中删除行是即时的。

     Delete from _ad
     where AdminDivisionID=(Select top 1 AdminDivisionID from AdminDivisions)
    

screenshot 2

  • 我删除了原始表中的所有触发器,外键,约束和索引。从精简表中删除一行仍然需要大约1000毫秒。

我接下来可以尝试什么?


更新1

这是执行计划(full size here)。引用此表的是FK - 以及表自己的PK索引。还不确定从哪里开始。

更新2

@Martin:这是SET STATISTICS IO ON的输出:

Table 'Instances'. Scan count 1, logical reads 12, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Locations'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'AwardsAdminDivisionsXtab'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'IndicatorResultComments'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'IndicatorResults'. Scan count 1, logical reads 35958, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Transactions'. Scan count 1, logical reads 155, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'LogicCheckViolations'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'AdminDivisions'. Scan count 1, logical reads 14, physical reads 0, read-ahead reads 0, lob logical reads 1, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'AspNet_SqlCacheTablesForChangeNotification'. Scan count 0, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

1 个答案:

答案 0 :(得分:3)

只是猜测因为我没有足够的信息:

  1. 也许目标表(AdminDivisions)是父表,并且有一个FK引用了AdminDivisions内的PK或UQ(唯一键)和
  2. 此FK具有ON DELETE CASCADE选项和
  3. 此FK未编入索引。
  4. 示例:

    CREATE TABLE dbo.ParentTable(
        ID INT IDENTITY(1,1) PRIMARY KEY,
        Name NVARCHAR(50) NOT NULL
    );
    GO
    CREATE TABLE dbo.ChildTable(
        ID INT IDENTITY(1,1) PRIMARY KEY,
        ParentID INT NOT NULL 
            REFERENCES dbo.ParentTable(ID) ON DELETE CASCADE
    );
    GO
    DELETE dbo.ParentTable
    WHERE ID = 1;       
    

    DELETE dbo.ParentTable ...语句之前dbo.ChildTable(ParentID)上创建索引的执行计划: enter image description here

    DELETE dbo.ParentTable ...dbo.ChildTable(ParentID))上创建索引之后CREATE INDEX IX1 ON dbo.ChildTable(ParentID);语句的执行计划enter image description here