ORACLE删除重复记录求优化

zznice 2015-10-19 11:45:59
DELETE
FROM "table"
WHERE "RowID" NOT IN (SELECT MAX("RowID")
FROM "table"
GROUP BY
"aaa",
"bbb",
"ccc"
HAVING COUNT(*) >= 1);

很普通的一条去重复语句,但是当数据量大时(两三万条记录),执行时间要几个小时,但这时执行括号内的查询很快
求优化方案
...全文
296 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
beyon2008 2015-10-22
  • 打赏
  • 举报
回复
是的啊,>= 1所有记录都符合条件啊,又not in是什么效果啊,逻辑没理清
z123zjf 2015-10-21
  • 打赏
  • 举报
回复
引用 9 楼 zznice 的回复:
[quote=引用 6 楼 songbintao 的回复:] 你having后面的语句一点用都没
这个是有用的,用来提取重复的[/quote] count(1)>1是取重复的,count(1)=1是取不重复的 你>=1,是何道理
陈灬风 2015-10-21
  • 打赏
  • 举报
回复
试试这个 delete from table where rowid in (select aa from (select rowid aa, row_number() over(partition by aaa, bbb, ccc order by a.aaa desc) rn, a.* from table a ) where rn > 1);
zznice 2015-10-21
  • 打赏
  • 举报
回复
引用 4 楼 beyon2008 的回复:
DELETE FROM "table" WHERE "RowID" NOT IN (SELECT MAX("RowID") FROM "table" GROUP BY "aaa", "bbb", "ccc" HAVING COUNT(*) >= 1); 这里前后的两个 "table"完全相同啊
因为是同一张表呀,不然呢?
zznice 2015-10-21
  • 打赏
  • 举报
回复
引用 6 楼 songbintao 的回复:
你having后面的语句一点用都没
这个是有用的,用来提取重复的
xu176032 2015-10-20
  • 打赏
  • 举报
回复
引用 3 楼 zznice 的回复:
[quote=引用 2 楼 beyon2008 的回复:] 说几点,第一点,在oracle里如果数据量大尽量别用not in,可以用left join然后判断从表主键为null的方式代替 第二点,你这个语句不知道是否写错了,不然完全没有意义,rowid明明是从table表select出来的,又not in,这个很矛盾 第三点,如果数据量大了对用到的条件列建索引提高查询速度是个解决办法
谢谢,数据量其实测试的时候也就不到四万的样子,但是做一次删除要将近两个小时,三四万的数据量对ORACLE来说应该是很小的数据了,而且执行括号内的语句很快,而且我把DELETE换成SELECT * 也很快可以得到结果 所以我总结:DELETE这条语句执行起来比SELECT要费时,导致变慢的原因主要在这里 另:not in前的rowid和后面的集合是进行选择比较,应该没有问题,但用not in效率确实会不高[/quote] sql逻辑没问题,not in确实效率会低,考虑换成not exists试试,另外按照你的描述,select很快,delete很慢,如果差距真的很大,可以考虑用存储过程,开游标查询,然后根据rowid循环删除,应该会比现在的直接delete快。
songbintao 2015-10-20
  • 打赏
  • 举报
回复
DELETE FROM "table" WHERE "RowID" NOT IN (SELECT MAX("RowID") FROM "table" GROUP BY "aaa", "bbb", "ccc");
songbintao 2015-10-20
  • 打赏
  • 举报
回复
你having后面的语句一点用都没
beyon2008 2015-10-20
  • 打赏
  • 举报
回复
既在又不在?
beyon2008 2015-10-20
  • 打赏
  • 举报
回复
DELETE FROM "table" WHERE "RowID" NOT IN (SELECT MAX("RowID") FROM "table" GROUP BY "aaa", "bbb", "ccc" HAVING COUNT(*) >= 1); 这里前后的两个 "table"完全相同啊
zznice 2015-10-19
  • 打赏
  • 举报
回复
引用 2 楼 beyon2008 的回复:
说几点,第一点,在oracle里如果数据量大尽量别用not in,可以用left join然后判断从表主键为null的方式代替 第二点,你这个语句不知道是否写错了,不然完全没有意义,rowid明明是从table表select出来的,又not in,这个很矛盾 第三点,如果数据量大了对用到的条件列建索引提高查询速度是个解决办法
谢谢,数据量其实测试的时候也就不到四万的样子,但是做一次删除要将近两个小时,三四万的数据量对ORACLE来说应该是很小的数据了,而且执行括号内的语句很快,而且我把DELETE换成SELECT * 也很快可以得到结果 所以我总结:DELETE这条语句执行起来比SELECT要费时,导致变慢的原因主要在这里 另:not in前的rowid和后面的集合是进行选择比较,应该没有问题,但用not in效率确实会不高
beyon2008 2015-10-19
  • 打赏
  • 举报
回复
说几点,第一点,在oracle里如果数据量大尽量别用not in,可以用left join然后判断从表主键为null的方式代替 第二点,你这个语句不知道是否写错了,不然完全没有意义,rowid明明是从table表select出来的,又not in,这个很矛盾 第三点,如果数据量大了对用到的条件列建索引提高查询速度是个解决办法
z123zjf 2015-10-19
  • 打赏
  • 举报
回复
having这个条件,有作用吗?

17,140

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧