10.删除重复记录最高效的删除重复记录方法(因为使用了ROWID)DELETE FROM EMP EWHERE E.ROWID > (SELECT MIN(X.ROWID)FROM EMP XWHERE X.EMP_NO = E.EMP_NO);  11.用TRUNCATE替代DELETE当删除表中的记录时,在通常情况下,回滚段(rollback segments)用来存放可以被恢复的信息。如果你没有COMMIT事务,Oracle会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之前的状况)而当运用TRUNCATE时,回滚段不再存放任何可被恢复的信息。当命令运行后,数据不能被恢复。因此很少的资源被调用,执行时间也会很短。(译者按:TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML)12.尽量多使用COMMIT只要有可能,在程序中尽量多使用COMMIT,这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少:COMMIT所释放的资源:a.回滚段上用于恢复数据的信息。b.被程序语句获得的锁c.redo log buffer中的空间d.Oracle为管理上述3种资源中的内部花费(译者按:在使用COMMIT时必须要注意到事务的完整性,现实中效率和事务完整性往往是鱼和熊掌不可得兼)13.计算记录条数和一般的观点相反,count(*) 比count(1)稍快,当然如果可以通过索引检索,对索引列的计数仍旧是最快的。例如 COUNT(EMPNO)(译者按:在CSDN论坛中,曾经对此有过相当热烈的讨论,作者的观点并不十分准确,通过实际的测试,上述三种方法并没有显著的性能差别)14.用Where子句替换HAVING子句避免使用HAVING子句,HAVING 只会在检索出所有记录之后才对结果集进行过滤。这个处理需要排序,总计等操作。如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销。例如:低效:SELECT REGION,AVG(LOG_SIZE)FROM LOCATIONGROUP BY REGIONHAVING REGION REGION !=‘SYDNEY’AND REGION !=‘PERTH’  高效:SELECT REGION,AVG(LOG_SIZE)FROM LOCATIONWHERE REGION REGION != ‘SYDNEY’AND REGION != ‘PERTH’GROUP BY REGION 

解决方案 »

  1.   

    删除重复记录使用rowid是正确的思路,不过sql并不一定要这样写,两次全表扫表速度能有多块?delete from t
     where rowid in (select rowid
                       from (select row_number() over(partition by id order by rowid) rn
                               from t)
                      where rn > 1)
    另外12.尽量多使用COMMIT不适用oracle
    这样做只会降低性能并引发错误
    这样做首先破坏事物
    而且如果你在一个打开的游标中批量更新一个大表,并且undo段不是很大的话,你经常commit会遇到ora-01555
    第三oracle的dbwr和lgwr会持续将数据刷新到数据文件和日志中,commit的时候只是做一些块清理的工作,如更新块头部的事物信息,释放锁啥的,多次提交并不会提升速度
      

  2.   

    [Quote=引用 1 楼  的回复:]删除重复记录使用rowid是正确的思路,不过sql并不一定要这样写,两次全表扫表速度能有多块?
    SQL codedelete from t
     where rowid in (select rowid
                       from (select row_number() over(partition by id order by rowid) rn
              ……
    [/Quote是啊。我也有这个疑惑。尽量多使用COMMIT,有个好处就是可以释放redo log buffer中的空间,因此可以提高性能。但在此,我有个疑惑,就是redo log buffer 中的redo entry可以由LGWR持续写入redo log file中了,这样也就把redo log buffer的空间给释放了,那么commit这样做岂不脱裤子放屁了?