實驗環境:
# | 類別 | 版本 |
1 | 操作系統 | Win10 |
2 | 數據庫 | Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production |
3 | 硬件環境 | T440p |
4 | 內存 | 8G |
建表:
CREATE TABLE tb_sc ( id NUMBER not null primary key, studentid int not null, courseid int not null, score int not null )
充值:
Insert into tb_sc select rownum,dbms_random.value(0,10000),dbms_random.value(1,5),dbms_random.value(0,150) from dual connect by level<=10000 order by dbms_random.random
待優化的SQL,此sql在數據量大時如僵死一般:
delete from tb_sc where (studentid,courseid,score) not in (select studentid,courseid,max(score) as score from tb_sc group by studentid,courseid);
優化方案1:
delete from tb_sc where id not in (select tb_sc.id from tb_sc,( select studentid,courseid,max(score) as score from tb_sc group by studentid,courseid ) tb_sc2 where tb_sc.studentid=tb_sc2.studentid and tb_sc.courseid=tb_sc2.courseid and tb_sc.score=tb_sc2.score)
優化方案2:
delete from tb_sc where not exists ( select null from tb_sc a, (select studentid,courseid,max(score) as score from tb_sc group by studentid,courseid) b where a.studentid=b.studentid and a.courseid=b.courseid and a.score=b.score and tb_sc.id=a.id)
優化方案3: 這種方案適用於delete語句太簡單而刪除數據較多的場合:
每次刪除一百條:
delete from tb_sc where (studentid,courseid,score) not in (select studentid,courseid,max(score) as score from tb_sc group by studentid,courseid) and rownum<101
放在循環里執行:
while(剩余數量>0){ 刪除符合條件的 }
優化方案四:將要保留的數據存入一張臨時表,刪除原表再倒回來,這種操作最大的優勢在於降低表的水位線。
相關帖子:
https://www.cnblogs.com/xiandedanteng/p/12232822.html
https://www.cnblogs.com/xiandedanteng/p/12232485.html
https://www.cnblogs.com/xiandedanteng/p/12231995.html
--2020年2月5日--