使用 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 不允许级联删除的原因之一,即不受控制地删除许多记录。
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 不允许级联删除的原因之一,即不受控制地删除许多记录。