zoukankan      html  css  js  c++  java
  • 删除海量数据之全表删除与部分删除

    删除海量数据时,如果想要提升性能,需要考虑的一个重要因素就是:如何减少日志操作?

    1. 全表删除
    全表删除的方式通常有3种:DROP, TRUNCATE, DELETE
    (1) DROP/TRUNCATE
    DROP和TRUNCATE是DDL操作,日志量都很少(只有回收数据页的记录,不记录页内每条数据的明细),都释放所有数据页,以及重置IAM、PFS、GAM、SGAM中的标志位,释放的数据页可被其他表使用;

    所不同的是,DROP同时也删除了系统目录里对于表的定义,相应的,表上所有定义的对象:INDEX、CONSTRAINT、TRIGGER等等也都将被删除,该表相关的IAM、PFS、GAM、SGAM页也将被释放(不只是重置标志位);

    (2) DELETE
    不带条件的DELETE可以用来删除全表数据,所有被删除的行都将被记录日志,做全表删除时效率较差,不推荐;

    2. 部分删除
    对于表中部分数据做删除,如果是分区表的话,直接TRUNCATE分区是最好了,即使是用DELETE删除分区中部分数据,效率也不会太差;

    如果不是分区表的话:

    (1) 删除表里少部分数据
    直接用DELETE删除; 

    (2) 删除表里大部分数据
    导出所需要保留的少数记录到临时表,然后TRUNCATE原表,再把临时表数据导回来;
    举例:

    SELECT * INTO tmp FROM TAB_NAME 
    WHERE DATE_COL > = GETDATE()-1
    
    TRUNCATE TABLE TAB_NAME
    
    INSERT INTO TAB_NAME 
    SELECT * FROM tmp
    
    DROP TABLE tmp

    如果不想再把临时表数据导回来,也可直接删除原表TAB_NAME,把tmp重命名为原表名,但不要忘了在tmp上创建原表的对象,如:索引/约束/触发器等等。

    EXEC sp_rename 'TAB_NAME', 'TAB_NAME_OLD'
    EXEC sp_rename 'tmp', 'TAB_NAME'
    --create index/constraint/trigger...on new TAB_NAME
    DROP TABLE TAB_NAME_OLD

    (3) 删除表里约一半数据

    这时,如果表上没有分区的话,就会慢的特别明显,的确没什么好的办法,只能用DELETE慢慢删除。

    另外,ORACLE中的NOLOGGING选项,类似于SQL Server中的BULK_LOGGED恢复模式,在批量数据操作时才有效,比如:SELECT…INTO(ORACLE中对应create table as select * from…),CREATE/ALTER INDEX 等等。并不是任何时候这个选项都有效的。

     小结

    (1) 海量数据的删除,尽量选择日志量较小的方式进行;
    (2) NOLOGGING选项/BULK_LOGGED恢复模式,在删除数据时,派不上用场,通常用在批量导入或更新数据时。

  • 相关阅读:
    结合使用allure当中的方法 让用例执行结果内 显示详细描述信息
    pytest-repeat插件,指定用例重复运行、重复运行次数
    pytest-xdist 分布式执行用例
    token
    使用pytest-ordering 来自定义用例执行顺序
    用例编写规则、命令行执行用例、用例执行的先后顺序
    python 中的doctest单元测试框架
    pytest 对用例mark标记分类(且用例也可按照分类来执行)
    学习webpack基本配置(一)
    (剑指offer)数组中出现次数超过一半的数字
  • 原文地址:https://www.cnblogs.com/shy1766IT/p/5184935.html
Copyright © 2011-2022 走看看