【发布时间】:2011-03-28 02:22:36
【问题描述】:
我有一个 SQL Server 2005 数据库,我尝试在适当的字段上放置索引,以加快具有数百万行的表中的记录 DELETE(big_table 只有 3 列),但现在DELETE 的执行时间甚至更长! (例如 1 小时与 13 分钟)
我在 to 表之间有关系,而我过滤 DELETE 的列在另一个表中。例如
DELETE FROM big_table
WHERE big_table.id_product IN (
SELECT small_table.id_product FROM small_table
WHERE small_table.id_category = 1)
顺便说一句,我也试过了:
DELETE FROM big_table
WHERE EXISTS
(SELECT 1 FROM small_table
WHERE small_table.id_product = big_table.id_product
AND small_table.id_category = 1)
虽然它的运行速度似乎比第一个稍快,但使用索引仍然比没有索引慢很多。
我在这些字段上创建了索引:
big_table.id_productsmall_table.id_productsmall_table.id_category
我的 .ldf 文件在 DELETE 期间增长了很多。
为什么我的表上有索引时我的 DELETE 查询会变慢?我认为它们应该运行得更快。
更新
好的,共识似乎是索引会大大减慢DELETE,因为必须更新索引。虽然,我仍然不明白为什么它不能一次DELETE所有行,而只在最后更新一次索引。
我从阅读的某些内容中得到的印象是,索引会加快 DELETE 的速度,因为它可以更快地搜索 WHERE 子句中的字段。
“在 DELETE 和 UPDATE 命令中搜索记录时,索引的作用与在 SELECT 语句中一样。”
但在文章后面,它说索引过多会损害性能。
鲍勃问题的答案:
- 表中有 5500 万行
- 4200 万行被删除
- 类似的
SELECT语句不会运行(抛出“System.OutOfMemoryException”类型的异常)
我尝试了以下 2 个查询:
SELECT * FROM big_table
WHERE big_table.id_product IN (
SELECT small_table.id_product FROM small_table
WHERE small_table.id_category = 1)
SELECT * FROM big_table
INNER JOIN small_table
ON small_table.id_product = big_table.id_product
WHERE small_table.id_category = 1
在运行 25 分钟后,两者都失败,并出现来自 SQL Server 2005 的以下错误消息:
An error occurred while executing batch. Error message is: Exception of type 'System.OutOfMemoryException' was thrown.
数据库服务器是具有 7.5 GB 内存的旧双核 Xeon 机器。这是我的玩具测试数据库 :) 所以它没有运行其他任何东西。
在我CREATE 之后,我是否需要对我的索引做一些特别的事情以使它们正常工作?
【问题讨论】:
-
表格有多少行?有多少行被删除?完成类似的 SELECT 语句需要多长时间?了解 SELECT 语句的执行速度可能有助于了解索引如何影响 DELETE。
-
这需要更长的时间,因为当您执行删除时,引用您的表的索引也必须更新。
-
5500 万行,42 行已删除,未完成,详情见上文
标签: sql sql-server subquery sql-delete