您的位置:首页 > 数据库

【SQL优化】一个生产线上剔重SQL的优化

2015-10-15 09:23 429 查看
在我们生产上有个表,记录的是工单派发的中间状态,派单程序各个模块之间会根据这个状态表分别对工作单执行不同的派法任务。

很明显在这个表中,根据工作任务单不允许重复。

但是很多时候,开发侧在设计的时候都不加主键(原因是害怕应用代码上报错,我去),所以我们需要定时去描述这个表,把重复的记录给删除。

而之前的删除代码是这样写的:

delete aiadmin.cct_trans_eomsintf

 where rowid in

       (select e.rod

          from (select o.rowid as rod, o.accept_id

                  from aiadmin.cct_trans_eomsintf o,

                       (select a.rowid as rid, a.accept_id

                          from aiadmin.cct_trans_eomsintf a,

                               (select accept_id, min(id) as creation_id

                                  from aiadmin.cct_trans_eomsintf

                                 group by accept_id

                                having count(accept_id) > 1) b

                         where a.accept_id = b.accept_id

                           and a.id = b.creation_id) d

                 where o.accept_id = d.accept_id

                   and o.rowid != d.rid

                 order by o.accept_id) e)

很明显,这个sql执行时要全表扫描trans表三次,最后一次使用rowid回表再删除记录。

因为这个中间表的记录不是很多,所以效率上并没有什么伤害。

但其实,下面的写法更高效:

delete from aiadmin.cct_trans_eomsintf w

 where w.rowid in (select new_rowid

                     from (select eos.rowid as new_rowid,

                                  row_number() over(partition by eos.accept_id order by eos.id, eos.rowid) as rid

                             from aiadmin.cct_trans_eomsintf eos)

                    where rid <> 1)

其只需要对trans表做一次全表扫描,效率明显高出很多。

ps,这里是根据accept_id重复就判定为重复,如果需要根据多个字段(或者全部字段)来判定为重复,那么在分组排序时需要将相应的字段全部加上。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: