现有一个经常被访问的表T,为了提高表T在数据量比较大的时候的对其进行查询等操作时候的速度,
建立了相同结构的一个副表T2和一个备份表T_OLD,表T中不断有数据插入,当T中的数据达到10万件的时候,进行数据的迁移和备份。具体操作如下:1。先将T2中的数据转移到备份表T_OLD中。
INSERT INTO T_OLD SELECT * FROM T2;2。上面的转移语句执行完后,将表T2删除。
DROP TABLE T2;3。再将表T改名成表T2。
RENAME T TO T2;4。然后,再创建同样结构的表T。
CREATE TABLE T AS SELECT * FROM T2 WHERE ROWNUM < 1;5。再为表T生成主键。
ALTER TABLE T ADD PRIMARY KEY (DVID, ALID, TM);6。提交。
COMMIT;现在的问题是:
1。在第3步改名的时候,经常出现NOWAIT的错误而失败,估计是可能有别的进程在访问表T,
而导致的失败。如果在第3步的时候对表T加锁的话,一个是不知道加锁可以成功否,再就是对表T加锁
后,不知道可不可以改名成功。
2。还有就是回滚的问题,因为DROP, RENAME, ALTER,CREATE 执行后都不能回滚,所以如果上面5步
中哪一步出错的话,数据库都不能回到出错前的状态。因为DB的优化是照上面设计的,所以尽量想照上面那样做。如果实在行不通的话,不知道有什么别的
什么好的优化方案,请大家多多指教!

解决方案 »

  1.   

    用的着怎么繁琐吗,用分区就行了, PARTITION!
    具体搜索一下oracle的分区表的资料,可以很方便的满足你的要求.
      

  2.   

    我想你这样做是太复杂了。
    不知道这样行不行?
    不要T2表,首先insert into T_old select * from T where 日期<今天;
    然后delete from T where 日期<今天;
    这样在同一个事务里就可以完成全部的备份删除操作。试试看。
      

  3.   

    我想你这样做是太复杂了。
    不知道这样行不行?
    不要T2表,首先insert into T_old select * from T where 日期<今天;
    然后delete from T where 日期<今天;
    这样在同一个事务里就可以完成全部的备份删除操作。试试看。
      

  4.   

    lemon223谢谢回复。
    因为用delete from T处理的时候,10万件的数据量的时候花费的时间太长了,所以后来才改成用drop
    的。
      

  5.   

    BoningSword,谢谢回复。用PARTITION的时候,在用范围分区的时候,如果想将10万挑以前的记录和10王条以后的记录分成两个区,过滤条件不知道应该怎么写好呢?
      

  6.   

    删除表记录可以用
    truncate table 表名;
      

  7.   

    因此,你的操作只剩两步了1。先将T2中的数据转移到备份表T_OLD中。
    INSERT INTO T_OLD SELECT * FROM T2;2。上面的转移语句执行完后,将表T2记录删除。
    TRUNCATE TABLE T2;
      

  8.   

    truncate 是最快的
    只有10条记录不用这么复杂的方案吧
      

  9.   

    在执行
    INSERT INTO T_OLD SELECT * FROM T2;这句的时候失败了,估计可能有别的进程在访问T2,因此对其先加锁
    lock T2 in share;上面这条语句执行后,进程估计处于等待状态,什么也没有做。因此
    又加上了nowait参数
    lock T2 in share nowait;此时程序执行成功了。程序虽然执行成功了,但是还是有不明白的地方。在执行lock T2 in share;
    语句后,进程既然处于等待状态,那就说明应该有别的进程对T2加锁了,所以
    才会等待,那后一条语句加上nowait参数(不等待马上响应)后,应该加锁也
    没有成功,可是程序为什么成功执行下去了呢?
      

  10.   

    You can also indicate if you do or do not want to wait to acquire the lock. If you specify the NOWAIT option, you only acquire the table lock if it is immediately available. Otherwise an error is returned to notify that the lock is not available at this time. In this case, you can attempt to lock the resource at a later time. If NOWAIT is omitted, the transaction does not proceed until the requested table lock is acquired. If the wait for a table lock is excessive, you might want to cancel the lock operation and retry at a later time; you can code this logic into your applications. 
      

  11.   

    ORARichard谢谢你多次的回复。
    最近在公司里居然上不了csdn了,真是很奇怪。还有谢谢大家的帮助。揭帖了。