DELETE test1 A 
 WHERE  A.dj<(SELECT MAX(dj) FROM test2 WHERE khdm=A.khdm AND spdm=A.spdm)
语句中的test1和test2表结构几乎一样,两张都是临时表在存储过程中使用,
其中两张表的khdm和spdm是有索引的,而DJ是没有索引,
DJ为1,2,3,4,5,的1位数字。
两张表都是由khdm和spdm唯一确定一条记录,每张表的记录数一般有200多万条,单执行这一句话
就要30多分钟,不知哪位高手能不能优化一下,这种速度太慢了。

解决方案 »

  1.   


    DELETE test1 A 
     WHERE EXISTS(SELECT 1 FROM test2 WHERE khdm=A.khdm AND spdm=A.spdm AND A.dj<dj)
      

  2.   

    --这样试试
    delete test1 a
    where not exists(select 1 from test2 b 
                     where a.khdm=b.khdm and a.spdm=b.spdm and a.dj>=b.dj)
      

  3.   

    如果删除的数据量比较多的话 先把索引禁用了http://blog.csdn.net/robinson1988/archive/2010/09/06/5867388.aspx
    看看这个博客 希望对你有帮助
      

  4.   

    DELETE test1 A WHERE EXISTS(SELECT 1 FROM test2 WHERE khdm=A.khdm AND spdm=A.spdm AND A.dj<dj)数据庞大的话禁用索引在执行…
      

  5.   

    楼主先根据前边的建议试试 把<换成exists 再关掉索引 
    但是 数据太多的话 无论怎么优化都不行的
    你可以分段删除 一次删掉1万 具体数字可以根据你的数据库的效率决定
      

  6.   


    既然是临时表 直接truncate  然后在插入 不是临时表
    DELETE test1 A  
     WHERE A.dj<(SELECT MAX(dj) FROM test2 WHERE khdm=A.khdm AND spdm=A.spdm)改成这样试试DELETE test1 A  
     WHERE exists<(SELECT 1 FROM test2 b WHERE b.khdm=A.khdm AND b.spdm=A.spdm
    and a.dj>b.dj)如果删除的数据量差不多接近全部删除可以考虑 禁用索引,然后在重建,否则没必要删除索引
    alter index idxname unsable/rebuild
      

  7.   

    DELETE FROM 
    test1  WHERE ROWID IN (
    SELECT ROWID FROM (
    SELECT
    A.*
    ROW_NUMBER()OVER(PARTITION BY A.khdm ,A.spdm ORDER BY DJ DESC) R
    FROM test1 A,test1 B
    WHERE  khdm=A.khdm AND spdm=A.spdm) C WHERE C.R=1)
      

  8.   

    删除ROWID应该是比较快的,可以改善下不用IN 用exists
      

  9.   

    oracle 对delete的数据要写入重做日志中,所以慢。 
    我感觉你的删除数据一定很大。所以很慢  。
    建议改变做法 ,先truncate 截断表中的数据。在把你需要保留的数据insert into  select 进来
      

  10.   

    可以insert into一个临时表,TRUNCATE原来表,在把数据导过来。