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恢复模式,在删除数据时,派不上用场,通常用在批量导入或更新数据时。

  • 相关阅读:
    ASP.NET事件顺序
    Discuz!NT 代码阅读笔记(9)DNT数据库中唯一的用户函数解析
    Discuz!NT代码阅读笔记(2)网站安装自动化论坛程序安装及初始化过程
    ASP.NET网站和ASP.NET应用程序的区别
    根据日期获得当天是星期几/蔡勒(Zeller)公式
    Discuz!NT 代码阅读笔记(8)DNT的几个分页存储过程解析
    Excel导出数据报表的类
    MSDN Magazine的下载
    openSuSE 11.0正式版发布了
    用lighttpd+mono在Linux上面跑ASP.NET程序
  • 原文地址:https://www.cnblogs.com/shy1766IT/p/5184935.html
Copyright © 2011-2022 走看看