使用 not exists 删除行需要 1 个多小时才能完成

Deleting rows using not exists taking over 1 hour to finish

Table 有一百万条记录。我正在使用 not exists.It 删除记录需要超过 1 小时。

我的示例代码:

delete from emp emp
       where empno=l_empno  --l_empno is parameter passing from procedure
       and not exists(select 1
                      from employees emps
                      where   emps.ename=  emp.ename);

尝试关闭日志记录并删除行,

alter table table_name nologging ;

testemp 和 testemp2 都是相同的 tables,具有相同的数据 testemp 需要一分钟,而 testemp2 只需要 1 秒

SQL> delete from testemp;

14336 rows deleted.

Elapsed: 00:01:04.12
SQL>
SQL>
SQL> alter table testemp2 nologging;

Table altered.

Elapsed: 00:00:02.86
SQL>
SQL> delete from testemp2;

14336 rows deleted.

Elapsed: 00:00:01.26
SQL>

编辑:

仅当我们使用 "Alter" 命令物理更改 table 时,才需要将 table 放回日志记录,如果您使用的是不需要提示,请参阅下面的示例

SQL> set timing on;
SQL> delete  from testemp2;

14336 rows deleted.

Elapsed: 00:00:00.51

Deleting data after reinserting same data into table now with nologging;



SQL> delete /*+NOLOGGING*/ from testemp2;

14336 rows deleted.
Elapsed: 00:00:00.28

SQL> select logging from user_Tables where table_name='TESTEMP2';

LOG
---
YES

有很多可能性:

首先,如果您在 emp.empn、emps.ename、emp.ename 上没有索引,您可能正在执行 table 扫描。检查你的执行计划。连接像 emane 这样的东西通常不是一个好主意——连接基于字符的数据类型比连接数字数据类型要慢。你有一个员工编号,你可以加入吗?您能否重新设计您的数据库,使这些 table 相关的字段成为可能?

接下来,如果您有级联删除,您可能会删除数百万条关联记录,即使您只删除了父项中的 1 条记录 table。

你可能有阻塞。

您可能试图一次删除如此多的记录,以至于在事务日志中记录删除所花费的时间太长,并且它需要增长,这会减慢速度。

您的触发器可能会减慢速度(如果是这样,请不要删除触发器。该触发器是出于业务原因而存在的。您可能需要重写它以使其更加基于集合。)

然后继续。

首先检查你的执行计划,看看你是否缺少索引或者你可能会遇到什么其他问题。 接下来检查您是否有触发器或级联增量。 即使是级联删除,也可以考虑是否要先批量删除子记录。这是许多 dbas 不允许级联删除的原因之一,即不受控制地删除许多记录。