我想使用 T-SQL 从包含 2000 万条记录的巨大表中删除几千条记录。该表有大约 20 个触发器,取决于它,并且都指或多或少相似的巨大表。即使我使用标识列值,删除也需要很长时间。如何在不禁用触发器或必须禁用最少触发器数的情况下删除这些记录?请帮忙。
4 回答
我在删除数据方面遇到了类似的问题。我在一个表中有 3.6 亿行。它具有“A”删除触发器来强制引用完整性。我试图删除大约 6000 万条记录。我可以采取两种方式,禁用删除触发器或限制我一次尝试删除的删除数量。我不得不一次将我的删除限制为 10,000 条记录。我认为这与不超载 tranlog 有关。
尝试以下
添加以下sps
Create PROCEDURE [dbo].[sysUserContextSet] --#1
@user_name varchar(14),
@terminal varchar(10) = NULL
AS
SET NOCOUNT ON
SET ANSI_WARNINGS OFF
declare @context varbinary(128)
set @context = CONVERT(varbinary(128), isNull(@user_name,'') + SPACE(14 - len(isNull(@user_name,'')))+ isNull(@terminal, '') + space(10 - len(isNull(@terminal, ''))))
set context_info @context
Create PROCEDURE [dbo].[sysUserContextClear] --#2
AS
SET NOCOUNT ON
SET ANSI_WARNINGS OFF
DELETE FROM sysUserContext WITH (ROWLOCK) WHERE spid=@@SPID
exec sysuserContextSet 'username'
delete ...
exec sysuserContextClear
这些触发器的存在是有原因的。禁用它们是一个糟糕的主意。
我要做的是首先查看触发器以确保它们以基于集合的方式运行(如果您在触发器中逐行进行,那么无论如何几千条记录都将花费很长时间。
假设您的触发器都正确编写,您可能还会遇到级联删除或 FK 问题,需要您在许多表中查找子记录(我们有一个需要检查 100 多个 FK)。在这种情况下,如果您不能加快触发器的速度,那么最好的办法是在循环中小批量工作。提交每一轮循环的事务,这样表就不会被锁定。然后如果可能的话,在下班时间进行处理。影响的 FK 表越多,您一次需要处理的批次就越小。
或者您可以设计您的数据库进行软删除(将记录标记为非活动,然后创建一个仅显示活动记录的视图)。这样,您根本不必删除。
对我来说,听起来您的问题在于删除这些行所花费的时间。
我同意 Zane,触发器的存在是有原因的,我不会禁用它们。
触发器是否需要时间?你能做些什么来加速触发器吗?
您用来识别和删除初始行的 sql 是什么?
我在更新时遇到了类似的问题。我最终分批进行更新。可以批量删除