2011-07-28 103 views
2

我们有一个表(比如说T1),在我们的SQL Server数据库中有大约16个其他表使用外键引用。数据通过一个带有LINQToSQL的ASP.NET应用程序来访问。当用户试图从T1中删除记录时,该语句会超时。所以我们决定先删除引用T1的表中的记录,然后删除T1中的记录。问题是从T1删除的速度不如预期那么快。SQL删除花费时间过长

我的问题是:即使记录本身没有任何'子女'记录,从很多其他表引用的表中删除这么耗时是否正常?

编辑:显然,超时的原因不是删除本身,而是从相同的DataContext检索数据的另一个查询。感谢您的建议,我已标记为回答为所有外键添加索引的建议,因为它改进了我们脚本的执行计划。

+2

您应该尝试在delete语句上运行查询分析器。大多数SQL Server实现都包含一个分析器,它将向您显示执行计划,您可以直接确定瓶颈,而不是让人们猜测速度是否是“正常”,这是一个非常主观,模糊的术语。 –

+1

您是否尝试过运行SQL Profiler来查看这些调用期间发生了什么?您可以获取SQL,然后运行执行计划并查看延迟的位置。 –

+5

你的外键有索引吗?看到这个老板栗:http://zootfroot.blogspot.com/2006/01/slow-sql-server-delete.html –

回答

1

我怀疑你可能需要看看你的子表上的索引。

听起来好像你的FK被设置为级联删除,所以我怀疑你的一些表没有包含父索引的索引作为索引中的第一个索引。

通过这种方式,您的删除将全面扫描子表 - 即使您已经删除了子记录,它仍然会检查您是否还有Cascade设置。

+0

你是对的,它扫描所有的子表......我检查了执行计划,并在检查它是否在表中有子记录后,它会为每个表执行删除语句。那么你认为用不采取行动来替代级联会大大减少执行时间吗? –

+0

并非如此,因为您仍然需要在路上或其他地方执行删除操作。查看删除的执行计划,以查看他们正在寻找的jow并检查您的索引。 –

2

在DB中定义关系时,可以将Delete rule设置为Cascade在SQL Server中。这样,当您从父表中删除记录时,它将自动从子表中删除。

请参见下图:

enter image description here

如果服用时间长了,你可能会设置其他限制,这将减缓下来 删除过程。

+2

从问题听起来像他们已经得到了这套。 –

+0

如果他使用linq-to-SQL并正确设置关系,则在提交更改时应删除子记录。 –

+0

问题是表已经使用级联,我想这是删除需要这么长时间的原因之一。我们首先删除了所有'子女',这样他们就不会被级联机制删除。显然这不是一个很好的解决方案:D –

1

的LINQ不会做批量删除,如果你有直接的记录集操作 - 相反,它可能在一个时间删除一个记录。

为提高性能,请使用存储过程来代替任何批量插入,更新或删除操作。

+0

参考:http://www.codeproject.com/KB/linq/BulkOperations_LinqToSQL.aspx – Chains

+1

我没有使用LINQ删除,而是我正在运行一个SQL删除语句。 –

+0

你的意思是Linq没有以任何方式参与删除语句?你是怎么做到的 - 用SQLcommand对象还是其他的东西?您是否尝试过使用存储过程? – Chains