论坛首页 综合技术论坛

Oracle删除数据减少IO的方法

浏览 4065 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-03-31  
今天有个表有很多数据需要删除,DBA很忙,我就自己动手了

delete from crm_customer t where t.corporation_id in (xxx,xxx,xxx,xxx.......xxx);


运行后发现数据库的CPU都消耗在了IOWait上面,我还以为是别人也在用这台机器作压力测试呢,东打听西打听没发现问题,结果DBA一个电话打来,说删除数据要这么做:

begin
for i in 90000018 .. 90000151 loop
 delete from crm_customer t where t.corporation_id = i;
 commit; 
end loop;
end;


而我那样做要回滚的数据太多,IO要求很高。

哈哈,又学了一手
   发表时间:2008-03-31  

不能这样用吗?

delete from crm_customer t
where
t.corporation_id >= 90000018
and t.corporation_id <= 90000151
0 请登录后投票
   发表时间:2008-04-02  
删个一百多条记录有这么慢吗?估计是楼主没建索引吧。另外,那个dba推荐的做法实际是最不值得推荐的,oracle里面最不好的做法就是经常commit。
0 请登录后投票
   发表时间:2008-04-03  
in是不能使用索引的。你应该使用or。即id = ??? or id =???这样的方式。你的问题是因为没应用到索引造成全表扫描。DBA给出的问题是一旦一个删除失败,会造成事务不完整。把commit移出循环比较好。不过你这种情况能具体知道每个id,所以即使事务失败也没什么。不过别的情况下绝对不能这么用。不然造成数据不完整的化,你怎么维护。
0 请登录后投票
   发表时间:2008-04-04  
问题出在 in 上
0 请登录后投票
   发表时间:2008-04-07  
魔力猫咪 写道
in是不能使用索引的。你应该使用or。即id = ??? or id =???这样的方式。你的问题是因为没应用到索引造成全表扫描。DBA给出的问题是一旦一个删除失败,会造成事务不完整。把commit移出循环比较好。不过你这种情况能具体知道每个id,所以即使事务失败也没什么。不过别的情况下绝对不能这么用。不然造成数据不完整的化,你怎么维护。

in也是有可能用索引的,例如:
lubo@LUBO> drop table t;

Table dropped.

lubo@LUBO> create table t(x int);

Table created.

lubo@LUBO> create index i on t(x);

Index created.

lubo@LUBO> insert into t(x) values(1);

1 row created.

lubo@LUBO> insert into t(x) values(2);

1 row created.

lubo@LUBO> commit;

Commit complete.

lubo@LUBO> set autotrace on exp
lubo@LUBO> select * from t;

         X
----------
         1
         2


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   TABLE ACCESS (FULL) OF 'T'



lubo@LUBO> select * from t where x in (1,2);

         X
----------
         2
         1


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   CONCATENATION
   2    1     INDEX (RANGE SCAN) OF 'I' (NON-UNIQUE)
   3    1     INDEX (RANGE SCAN) OF 'I' (NON-UNIQUE)



lubo@LUBO>
0 请登录后投票
   发表时间:2008-04-09  
这个 DBA 告诉你的方法也一般,弄不好就出事情
0 请登录后投票
   发表时间:2008-04-09  

我们DBA常说的表截断不知道是不是不用回滚内存?
0 请登录后投票
   发表时间:2008-04-10  
个人感觉2楼的方法不错啊,呵呵
0 请登录后投票
   发表时间:2008-04-11  
抛出异常的爱 写道

我们DBA常说的表截断不知道是不是不用回滚内存?

不是
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics