谜团:SQL表中的缓慢删除
我有一个包含29列和3000-4000行的SQL表。它有几个空间域(2个几何和1个地理),但其他方面没有什么特别的 在生产和开发环境中,从该表中删除一行现在需要大约1000毫秒谜团:SQL表中的缓慢删除,sql,sql-server,tsql,sql-server-2012,query-optimization,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) 以下是我(在开发环境中)尝试的内容: 我克隆了这个表,并煞费苦心地重新创建了它的所有触发器、外键、约束和索引。从克
Delete from AdminDivisions
where AdminDivisionID=(Select top 1 AdminDivisionID from AdminDivisions)
以下是我(在开发环境中)尝试的内容:
- 我克隆了这个表,并煞费苦心地重新创建了它的所有触发器、外键、约束和索引。从克隆中删除行是即时的
Delete from _ad where AdminDivisionID=(Select top 1 AdminDivisionID from AdminDivisions)
- 我已经从原始表中删除了所有触发器、外键、约束和索引。从精简表中删除一行平均需要1000毫秒左右李>
更新1 这是执行计划()。它是引用此表的FKs,以及该表自己的PK索引。还是不知道该从这里走到哪里 更新2 @马丁:这是设置统计IO的输出:
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.
只是猜测,因为我没有足够的信息:
AdminDivisions
)是一个父表,并且有一个引用PK的FK或AdminDivisions
中/的UQ(唯一键),并且选项和
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;
在dbo.ChildTable(ParentID)
上创建索引之前,DELETE dbo.ParentTable…
语句的执行计划:
DELETE dbo.ParentTable…
语句在dbo.ChildTable(ParentID)
上创建索引后的执行计划(在dbo.ChildTable(ParentID)上创建索引IX1;
):
我只是猜测一下,因为我没有足够的信息:
AdminDivisions
)是一个父表,并且有一个引用PK的FK或AdminDivisions
中/的UQ(唯一键),并且选项和
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;
在dbo.ChildTable(ParentID)
上创建索引之前,DELETE dbo.ParentTable…
语句的执行计划:
DELETE dbo.ParentTable…
语句在dbo.ChildTable(ParentID)
上创建索引后的执行计划(在dbo.ChildTable(ParentID)上创建索引IX1;
):
我只是猜测一下,因为我没有足够的信息:
AdminDivisions
)是一个父表,并且有一个引用PK的FK或AdminDivisions
中/的UQ(唯一键),并且选项和
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;
在dbo.ChildTable(ParentID)
上创建索引之前,DELETE dbo.ParentTable…
语句的执行计划:
DELETE dbo.ParentTable…
语句在dbo.ChildTable(ParentID)
上创建索引后的执行计划(在dbo.ChildTable(ParentID)上创建索引IX1;
):
我只是猜测一下,因为我没有足够的信息:
AdminDivisions
)是一个父表,并且有一个引用PK的FK或AdminDivisions
中/的UQ(唯一键),并且选项和
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;
在dbo.ChildTable(ParentID)
上创建索引之前,DELETE dbo.ParentTable…
语句的执行计划:
DELETE dbo.ParentTable…
语句在dbo.ChildTable(ParentID)
上创建索引后的执行计划(在dbo.ChildTable(ParentID)上创建索引IX1;
):
没有订单,top 1是什么意思?另外,它实际上在等待什么(例如,请参阅sys.dm_exec_requests中的wait_type)?如果你要这么做,为什么不直接说
DELETE TOP(1)dbo.\u ad代码>?另外请注意,当您采取诸如删除所有索引(包括集群索引)之类的激烈措施时,这可能会导致表扫描。显示执行计划。您是否有引用AdminDivisions
中PK/UQ(唯一键)的FKs?可能这些FK没有索引,因此导致扫描。在事务
和指示符结果
中有多少行?他们都有扫描而不是搜索。同时,的输出将统计IO设置为ON代码>请?看来您需要在指标结果
中添加一个索引,以使FK验证更有效。另外,在事务中添加缺少的索引也可能不会有什么坏处
如果没有订单,TOP1是什么意思?另外,它实际上在等待什么(例如,请参阅sys.dm_exec_requests中的wait_type)?如果你要这么做,为什么不直接说DELETE TOP(1)dbo.\u ad代码>?另外请注意,当您采取诸如删除所有索引(包括集群索引)之类的激烈措施时,这可能会导致表扫描。显示执行计划。您是否有引用AdminDivisions
中PK/UQ(唯一键)的FKs?可能这些FK没有索引,因此导致扫描。在事务
和指示符结果
中有多少行?他们都有扫描而不是搜索。同时,的输出将统计IO设置为ON代码>请?看来您需要在指标结果
中添加一个索引,以使FK验证更有效。另外,在事务中添加缺少的索引也可能不会有什么坏处
如果没有订单,TOP1是什么意思?另外,它实际上在等待什么(例如,请参阅sys.dm_exec_requests中的wait_type)?如果你要这么做,为什么不直接说DELETE TOP(1)dbo.\u ad代码>?还请注意