ITPUB论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

返回列表 发新帖
更多
查看: 2322|回复: 9

删除太慢了,请问如何加快? [复制链接]

注册会员

Victor

精华贴数
0
技术积分
1534
社区积分
8
注册时间
2005-1-31
论坛徽章:
4
授权会员
日期:2005-11-04 15:12:46ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:442011新春纪念徽章
日期:2011-02-18 11:43:32
发表于 2006-6-21 15:10:27 |显示全部楼层
删除重复记录前,先查询了一下要删除的有多少行:
select count(*)
  from tab1 a
where a.rowid < (select max(b.rowid)
                    from tab2 b
                   where a.col1 = b.col1
                     and a.col2 = b.col2);

查询的结果有12万条记录,然后将select count(*)改为delete后开始执行…………4个小时了,现在还没执行完。
有什么办法能加快吗?

版主

永远的巴乔

精华贴数
26
技术积分
19863
社区积分
6587
注册时间
2003-10-15
论坛徽章:
122
ITPUB8周年纪念徽章
日期:2009-09-27 10:21:222010广州亚运会纪念徽章:武术
日期:2011-01-25 18:04:512010广州亚运会纪念徽章:板球
日期:2011-01-27 12:34:032011新春纪念徽章
日期:2011-02-18 11:43:342010广州亚运会纪念徽章:保龄球
日期:2011-03-18 17:36:40现任管理团队成员
日期:2011-05-07 01:45:08ITPUB官方微博粉丝徽章
日期:2011-06-28 19:45:36茶鸡蛋
日期:2011-08-07 09:46:33紫蛋头
日期:2011-11-11 13:56:28灰彻蛋
日期:2011-10-19 10:41:16ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282011新春纪念徽章
日期:2011-01-25 15:42:56
发表于 2006-6-21 15:18:02 |显示全部楼层
用分析函数,参考:

[php]

删除重复数据的一种高效的方法
发表人:yaanzy | 发表时间: 2005年二月18日, 13:57
表demo是重复拷贝自dba_objects,有88万左右,不重复的是27323,没有索引
方法一:delete from demo a where a.rowid <> (select max(rowid) from demo b where
                                                                      b.object_id=a.object_id);
            耗时:几个小时以上
方法二: delete from demo where rowid in
              (select rid from
                          (select rowid rid,row_number() over(partition by object_id order by rowid) rn
                             from demo)
               where rn <> 1 );
   耗时:30秒
方法三: create table demo2 as
              select object_id,owner... from
                       (select demo.*,row_number() over(partition by object_id order by rowid) rn from demo)
                         where rn = 1;
              truncate table demo; insert into demo select * from demo2; drop table demo2;
共耗时: 10秒,适合大数据量的情况,产生更少回滚量;

..
[/php]

使用道具 举报

版主

永远的巴乔

精华贴数
26
技术积分
19863
社区积分
6587
注册时间
2003-10-15
论坛徽章:
122
ITPUB8周年纪念徽章
日期:2009-09-27 10:21:222010广州亚运会纪念徽章:武术
日期:2011-01-25 18:04:512010广州亚运会纪念徽章:板球
日期:2011-01-27 12:34:032011新春纪念徽章
日期:2011-02-18 11:43:342010广州亚运会纪念徽章:保龄球
日期:2011-03-18 17:36:40现任管理团队成员
日期:2011-05-07 01:45:08ITPUB官方微博粉丝徽章
日期:2011-06-28 19:45:36茶鸡蛋
日期:2011-08-07 09:46:33紫蛋头
日期:2011-11-11 13:56:28灰彻蛋
日期:2011-10-19 10:41:16ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282011新春纪念徽章
日期:2011-01-25 15:42:56
发表于 2006-6-21 15:18:44 |显示全部楼层
建议用方法二

使用道具 举报

注册会员

Victor

精华贴数
0
技术积分
1534
社区积分
8
注册时间
2005-1-31
论坛徽章:
4
授权会员
日期:2005-11-04 15:12:46ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:442011新春纪念徽章
日期:2011-02-18 11:43:32
发表于 2006-6-21 15:37:27 |显示全部楼层
谢谢~!我刚搜了一下,发现还有种办法:

delete cz where (c1,c10) in (select c1,c10 from cz group by c1,c10 having count(*)>1) and rowid not in
(select min(rowid) from cz group by c1,c10 having count(*)>1);

使用道具 举报

注册会员

高级会员

精华贴数
0
技术积分
10615
社区积分
325
注册时间
2001-10-25
论坛徽章:
26
ITPUB元老
日期:2005-02-28 12:57:00生肖徽章:兔
日期:2006-09-26 21:29:55生肖徽章:兔
日期:2006-09-07 17:01:32生肖徽章:兔
日期:2006-09-07 17:02:25生肖徽章:兔
日期:2006-09-07 17:02:46生肖徽章:兔
日期:2006-09-07 17:06:29生肖徽章:兔
日期:2006-09-18 05:26:00生肖徽章:狗
日期:2006-10-06 13:28:27生肖徽章:狗
日期:2006-10-08 05:28:34生肖徽章2007版:鸡
日期:2008-01-02 17:35:53生肖徽章:兔
日期:2006-09-07 10:21:09生肖徽章:兔
日期:2006-09-07 10:16:46
发表于 2006-6-21 15:50:23 |显示全部楼层
最初由 coohoo 发布
[B]谢谢~!我刚搜了一下,发现还有种办法:

delete cz where (c1,c10) in (select c1,c10 from cz group by c1,c10 having count(*)>1) and rowid not in
(select min(rowid) from cz group by c1,c10 having count(*)>1); [/B]


这些方法效率都是很低的
建议还是使用oracle 的分析函数比较快一点的

使用道具 举报

注册会员

老会员

精华贴数
0
技术积分
1161
社区积分
2
注册时间
2002-6-20
论坛徽章:
4
ITPUB元老
日期:2006-06-01 09:52:25ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44生肖徽章2007版:鼠
日期:2008-01-02 17:35:53
发表于 2006-6-21 16:04:39 |显示全部楼层
要考虑删除的重复记录占总记录数的比例。

使用道具 举报

注册会员

Victor

精华贴数
0
技术积分
1534
社区积分
8
注册时间
2005-1-31
论坛徽章:
4
授权会员
日期:2005-11-04 15:12:46ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:442011新春纪念徽章
日期:2011-02-18 11:43:32
发表于 2006-6-21 16:54:24 |显示全部楼层
方法二: delete from demo where rowid in
              (select rid from
                          (select rowid rid,row_number() over(partition by object_id order by rowid) rn
                             from demo)
               where rn <> 1 );
对于此方法,如果判断两个字段是否重复,我这样写:
delete from demo where rowid in
              (select rid from
                          (select rowid rid,row_number() over(partition by object_id,object_id2 order by rowid) rn
                             from demo)
               where rn <> 1 );
就是增加了第2个字段object_id2,但发现结果不对。应该怎么写?

使用道具 举报

版主

版主

精华贴数
10
技术积分
18552
社区积分
1830
注册时间
2004-9-9
论坛徽章:
37
数据库板块每日发贴之星
日期:2007-07-18 01:03:092008北京奥运纪念徽章:篮球
日期:2008-12-03 11:23:03生肖徽章2007版:兔
日期:2008-12-12 19:41:10数据库板块每日发贴之星
日期:2009-02-19 01:01:04生肖徽章2007版:羊
日期:2009-03-02 15:40:09生肖徽章2007版:虎
日期:2009-03-02 15:42:53生肖徽章2007版:牛
日期:2009-09-10 11:14:59祖国60周年纪念徽章
日期:2009-10-09 08:28:002010新春纪念徽章
日期:2010-01-04 08:33:082010年世界杯参赛球队:日本
日期:2010-02-26 11:04:222010新春纪念徽章
日期:2010-03-01 11:20:512011新春纪念徽章
日期:2011-01-25 15:41:01
发表于 2006-6-21 21:46:29 |显示全部楼层
oracle的删除和更新操作本来就是很慢的,没有更好的办法,如果你预先分区还好一些

使用道具 举报

注册会员

珍惜健康 珍惜幸福

精华贴数
0
技术积分
2270
社区积分
11
注册时间
2004-3-15
论坛徽章:
3
数据库板块每日发贴之星
日期:2006-02-18 01:02:33会员2007贡献徽章
日期:2007-09-26 18:42:10ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44
发表于 2006-6-22 11:02:16 |显示全部楼层
如果没有大的影响,建议 CTAS

使用道具 举报

注册会员

Lighten Up

精华贴数
0
技术积分
1551
社区积分
64
注册时间
2006-3-5
论坛徽章:
2
授权会员
日期:2006-06-26 09:16:31会员2007贡献徽章
日期:2007-09-26 18:42:10
发表于 2006-6-22 11:42:20 |显示全部楼层
没有哪种是最优的,
根据数据(分布,多少等等)情况,上面几种方式会用不一样的表现。

使用道具 举报

相关内容推荐
您需要登录后才可以回帖 登录 | 注册

TOP技术积分榜 社区积分榜 徽章 电子杂志 团队 统计 邮箱 虎吧 老博客 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档 | IT博客
CopyRight 1999-2011 itpub.net All Right Reserved. 北京皓辰网域网络信息技术有限公司版权所有 联系我们 网站律师 隐私政策 知识产权声明
京ICP证:060528号 北京市公安局海淀分局网监中心备案编号:1101082001 广播电视节目制作经营许可证:编号(京)字第1149号
  
回顶部