Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database DB2:从表中清除大量记录_Database_Performance_Db2_Db2 Luw - Fatal编程技术网

Database DB2:从表中清除大量记录

Database DB2:从表中清除大量记录,database,performance,db2,db2-luw,Database,Performance,Db2,Db2 Luw,我正在为LUW使用DB29.7FP5。我有一个250万行的表,我想删除大约100万行,这个删除操作分布在整个表中。我用5条delete语句删除数据 delete from tablename where tableky between range1 and range2 delete from tablename where tableky between range3 and range4 delete from tablename where tableky between range5 a

我正在为LUW使用DB29.7FP5。我有一个250万行的表,我想删除大约100万行,这个删除操作分布在整个表中。我用5条delete语句删除数据

delete from tablename where tableky between range1 and range2
delete from tablename where tableky between range3 and range4
delete from tablename where tableky between range5 and range5
delete from tablename where tableky between range7 and range8
delete from tablename where tableky between range9 and range10
执行此操作时,前3次删除正常工作,但第4次删除失败,DB2挂起,什么也不做。以下是我遵循的流程,请帮助我:

1. Set following profile registry parameters: DB2_SKIPINSERTED,DB2_USE_ALTERNATE_PAGE_CLEANING,DB2_EVALUNCOMMITTED,DB2_SKIPDELETED,DB2_PARALLEL_IO

2.Alter bufferpools for automatic storage.

3. Turn off logging for tables (alter table tabname activate not logged initially) and delete records

4. Execute the script with +c to make sure logging is off
删除如此大量数据的最佳做法是什么?为什么从同一个表中删除相同性质的数据会失败?

DB2不太可能“挂起”——更可能是在事务日志中填充了
DELETE
操作之后进行回滚


确保您是在每个
DELETE
语句之后提交的。如果您使用DB2CLP的
+c
选项执行脚本,那么请确保在每个
DELETE
之间包含一个显式的
COMMIT
语句,删除具有数百万行的数据的最佳实践是在删除之间使用COMMIT。在您的情况下,可以在每个delete语句之后使用commit

commit所做的是清除事务日志,并为其他delte操作提供执行空间

或者instad of 5 delete语句使用loop并将delete语句传递给delete,在循环的一次迭代后执行一次commit,那么数据库将永远不会挂起,同时您的数据将被删除

用这样的东西

while(count<no of records)
delete from (select * from table fetch fist 50000 records only)
commit;
count= total records- no of records.

while(count这始终是一项棘手的任务。事务的大小(例如用于安全回滚)受事务日志大小的限制。事务日志不仅由您的sql命令填充,还由同时使用db的其他用户的命令填充

我建议使用以下方法之一或组合使用

1.承诺 经常使用commmits-在您的情况下,我会在每个delete命令之后放置一个commit

2.增加事务日志的大小 我记得默认的db2事务日志不是很大。事务日志的大小应该分别为每个db计算/调整。参考和更多详细信息

3.存储过程 写入和调用存储过程,该存储过程在块中进行删除,例如:

4.使用替换选项导出+导入 在某些情况下,当我需要清除非常大的表或只留下少量记录(并且没有FK约束)时,我使用export+import(替换)。替换导入选项非常具有破坏性-它在开始导入新记录之前清除整个表(参考),因此请确保您正在执行的操作,并在之前进行备份。对于此类敏感操作,我创建了3个脚本并分别运行:备份、导出、导入。以下是导出脚本:

echo '===================== export started '; 
values current time;

export to tablename.del of del  
select *  from tablename where (tableky between 1 and 1000 
    or tableky between 2000 and 3000 
    or tableky between 5000 and 7000 
    ) ; 
echo '===================== export finished ';  
values current time;
以下是导入脚本:

echo '===================== import started ';  
values current time;

import from tablename.del of del  allow write access commitcount 2000
-- !!!! this is IMPORTANT and VERY VERY destructive option  
replace  
into tablename ;

echo '===================== import finished ';
5.截断命令 版本9.7中的Db2引入了TRUNCATE语句,该语句:

删除表中的所有行。

基本上:

TRUNCATE TABLE <tablename> IMMEDIATE
TRUNCATE表立即数
我没有在db2中使用TRUNCATE的经验,但在其他一些引擎中,该命令非常快,并且不使用事务日志(至少不是以通常的方式)。请检查所有详细信息或。作为解决方案4,此方法也非常具有破坏性-它会清除整个表,因此在发出命令之前要非常小心。请确保先执行表/db backup的前一状态

请注意何时执行此操作 当数据库上没有其他用户时,或者通过锁定表来确保这一点

关于回滚的注意事项
在事务数据库(如db2)中,回滚可以将数据库状态恢复到事务启动时的状态。在方法1、3和4中,这是无法实现的,因此如果需要“恢复到原始状态”功能,确保这一点的唯一选项是第2种方法-增加事务日志,这对每个人都有好处,是指向我的developerWorks文章中关于同一问题的链接。我尝试了不同的方法,我在这篇文章中分享的方法非常适合我

delete from ordpos where orderid in ((select orderid from ordpos where orderid not in (select id from ordhdr) fetch first 40000 rows only));

希望这能解决您的查询:)

如果选择仅获取前10行的位置可以拉入几块记录,例如10块,那么您可以将其作为输入输入输入到另一个脚本中,然后删除这些记录。冲洗并重复…

我在博客上分享了我的经验。请参考这个。
delete from ordpos where orderid in ((select orderid from ordpos where orderid not in (select id from ordhdr) fetch first 40000 rows only));