我有一个表叫test,里面有3千万条数据,现在我想从表的最后面数据开始删除二千万条,只保留最前面的一千万条,请问该怎么做呢?
谢谢了

解决方案 »

  1.   

    delete from table where id>=
    (
    select id from 
    (select id,rownum as rn from table order by id )
    where rn=20000000
    )实际上你删除如此多的数据,最好的方式是:create table table_temp
    as
    select * from table 
    where rownum<=1000000//1000w
    order by id;
    truncate table table;
    insert into table
    as select * from table_temp;
      

  2.   

    最好的方式是:
    利用存储过程分批delete ,然后commit
    否则会超慢,具体的存储过程就不在这里贴
      

  3.   

    三楼的SQL语句有可能得到的记录不是最前面1000W条记录create   table   table_temp 
    as 
    select   *   from   table   
    where   rownum <=1000000//1000w    (************)
    order   by   id;                   (************)
    truncate   table   table; 
    insert   into   table 
    as   select   *   from   table_temp; 关键在于该条SQL语句中的ROWNUM这个伪列,它不受同层SQL语句ORDER BY 子句的影响
      

  4.   

    建议增加主键(流水号,通过序列赋值)字段xxxkey
    这样就可以准确删除:
    delete tab1 where xxxkey in(select * from (select xxxkey from tab1 order by xxxkey desc) where rownum<=20000000)
      

  5.   

    如何查询后2000万笔记录:
    select * 
    from table 
    where rownum = 200000000 
    order by asc
      

  6.   

    5楼说的是对的。
    需要先order by 再rownum   <=1000000//1000w  
      

  7.   

    楼上有一个说是用truncate table的,我觉得这个方法在如此大数据量的情况下还是会很慢。我比较支持做一个存储过程,在存储过程中使用一个循环来做分批地删除,我测试过,在每次删除1~5万条数据的时候(根据主键,这样会提高速度)会得到比较满意的速度。
      

  8.   

    如果你用Delete来删除数据,那么对你的查询来说 ,速度不会提升太快,需要降低高水位线
      

  9.   

    1, 先取前1000万条件记录BATCH INSERT到temp表中
    2, truncate 当前表
    3, 再把temp表中的1000万记录BATCH INSERT到当前表
    注意取前1000万条件记录时不能用ROWNUM, 而应该利用ROWID
      

  10.   

    较好的办法是:新建一个同表,然后导入前面的1000W条,再drop掉原表,最后重命令新表这样做可以优化性能,还可重建索引等
      

  11.   

    确认是否需要在线删除,而不能影响业务应用?
    需要的话,分批删除,最后再MOVE,重建索引,分析表;
    不需要的话,直接取前1千万条记录重建一张表。另外,碰到这种大表,别忘了采用表分区。
      

  12.   

    比较认同yown:
    发表于:2008-01-31 17:31:0813楼 得分:0
    较好的办法是:新建一个同表,然后导入前面的1000W条,再drop掉原表,最后重命令新表这样做可以优化性能,还可重建索引等这样同时优化的做法。
      

  13.   

    1. create table table_new as select * from table_old where rownum <= 1000000;
    2. truncate table table_old ;
    3. insert into table_old select * from table_new;
    4. drop table table_new;
      

  14.   

    13楼太客气了,你的方法不是比较好,而是对于大数据量删除和UPDATE的正解. 原因很简单,不论你是删除还是UPDATE大量数据都将产生大量的回滚及REDO信息, 而INSERT所产生的这些信息是最少的,也是最快的. 最后将中间表数据再INSERT回原表(之前删除也好,TRANCATE也好)还是忽略了这一层, 只能说不得要领. 或者他们不知道ORACLE有RENAME一个TABLE的功能. 相当于只是该一下数据字典, 1秒就够了. 其实如果有人长去ASKTOM.ORACLE.COM的话,ORACLE的TOM大哥很早以前就已经介绍过这种把删除或UPDATE后的结果插入一个临时表,然后DROP旧表+改名的方案.至于什么叫这个表的最后2000W条记录, 就该楼主自己去回答了。