简体   繁体   English

从具有约20个触发器的表中删除记录-SQL

[英]Deleting records from a table with about 20 triggers- SQL

I want to delete a few thousand records using T-SQL from a huge table with 20 million records. 我想使用T-SQL从具有2000万条记录的巨大表中删除几千条记录。 This table has about 20 triggers depending on it and all referring to more or less similar huge table. 该表取决于它,大约有20个触发器,所有触发器都或多或少地引用了类似的巨大表。 Deletion is taking a long time even when I use the identity column values. 即使使用身份列值,删除也要花费很长时间。 How do I delete these records without disabling the triggers or having to disable minimum number of triggers? 如何删除这些记录,而不禁用触发器或必须禁用最小数量的触发器? Please help. 请帮忙。

I have worked a similar problem for deleting data. 我曾为删除数据工作过类似的问题。 I had 360 million rows in a table. 我的表中有3.6亿行。 It had "A" delete trigger to enforce referential integrity. 它具有“ A”删除触发器以强制执行参照完整性。 I was trying to delete about 60 million records. 我试图删除大约6000万条记录。 I could go two ways, disable the delete trigger or limit the number of deletes that I was trying to delete at one time. 我可以采用两种方法,禁用删除触发器或限制一次尝试删除的删除次数。 I had to limit my deletes to 10,000 records at a time. 我必须一次将删除限制为10,000条记录。 I think this had to do with not overloading the tranlog. 我认为这与不超载笔录有关。

Try the following 尝试以下

add the following sps 添加以下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

To me it sounds like your issue is with the time it is taking to delete these rows. 在我看来,您的问题在于删除这些行所花费的时间。

I agree with Zane, the triggers are there for a reason and I would not disable them. 我同意Zane的观点,触发器是有原因的,我不会禁用它们。

Are the triggers taking the time? 触发器花时间吗? Can you do anything to speed up the triggers? 您能做些什么来加快触发器的速度吗?

What is the sql you are using to identify and delete the initial rows? 您用来识别和删除初始行的SQL是什么?

I ran into a similar issue with updates. 我在更新时遇到了类似的问题。 I ended up doing the updates in batches. 我最终分批进行了更新。 You could delete in batches 您可以批量删除

Those triggers are there for a reason. 这些触发器在那里是有原因的。 Disabling them is a poor idea. 禁用它们是一个糟糕的主意。

What I would do is first look at the triggers to ensure they are operating in a set-based fashion (if you are going row by row in a trigger, then a few thousand records will take a long time no matter what. 我要做的是首先查看触发器,以确保它们以基于集合的方式进行操作(如果您要在触发器中一行一行地进行操作,那么无论如何,数千条记录都将花费很长时间。

Assuming your triggers are all correctly written, you may also have an issue with cascading deletes or FKs that require you to look for child records in many tables (We have one with over 100 FKs to check). 假设所有触发器均已正确编写,则级联删除或FK可能还存在问题,要求您在许多表中查找子记录(我们要检查的表中有100多个FK)。 In this case and if you can't speed up the triggers, then the best bet is to work in small batches in a loop. 在这种情况下,如果您无法加快触发器的速度,那么最好的选择就是循环小批量工作。 Commit the transactions for each round of the loop so the table is not locked up. 在循环的每一轮都提交事务,因此不会锁定表。 Then if possible do the processing during off hours. 然后,如果可能,请在下班时间进行处理。 The more FK tables affected the smaller the batch you need to process at a time. 受影响的FK表越多,一次需要处理的批次越小。

Or you could design your database to do soft deletes (mark records as inactive and then crete a view that shows only the active records). 或者,您可以将数据库设计为进行软删除(将记录标记为非活动,然后创建仅显示活动记录的视图)。 This way you don't have to delete at all. 这样,您根本不必删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM