原文:【SQL Server性能优化】删除大量数据的方法比较


如果你要删除表中的大量数据,这个大量一般是指删除大于10%的记录,那么如何删除,效率才会比较高呢? 而如何删除才会对系统的影响相对较小呢?

下面先做一个实验,然后对这个实验的结果进行分析,然后得出结论。

1、创建数据库


  1. use master
  2. go
  3. if exists(select * from sys.databases where name = 'test')
  4. drop database test
  5. go
  6. create database test
  7. go

2、创建表


  1. use test
  2. go
  3. if exists(select * from sys.tables where name = 't')
  4. drop table t
  5. go
  6. create table t(i int,v varchar(100) default replicate('a',100)
  7. ,vv varchar(100) default replicate('a',100),
  8. vvv varchar(100) default replicate('a',100));

3、插入数据

用下面的代码添加100000条记录,消耗9秒:


  1. declare @i int;
  2. set @i = 1
  3. begin tran
  4. while @i <= 100000
  5. begin
  6. insert into t(i) values(@i)
  7. set @i = @i + 1
  8. end
  9. commit tran

而如果用下面的代码,添加100000条记录,消耗43秒:


  1. declare @i int;
  2. set @i = 1
  3. while @i <= 100000
  4. begin
  5. begin tran
  6. insert into t(i) values(@i) --没执行一次就提交一次,效率较差
  7. commit tran
  8. set @i = @i + 1
  9. end

重复插入数据,消耗1分38秒


  1. insert into t
  2. select *
  3. from t
  4. go 6

最后总共插入了640万条数据。

4、建立索引

create index idx_t_idx1 on t(i)

5、进行如下设置,是为了预防SQL Server使用太多内存,而导致死机


  1. sp_configure 'show advanced option',1
  2. go
  3. reconfigure
  4. go
  5. sp_configure 'max server memory (MB)',3584
  6. go
  7. reconfigure
  8. go

6、把上面创建的表t数据,复制成t1和t2两个表,对t1表建立索引


  1. if exists(select * from sys.tables where name = 't1')
  2. drop table t1
  3. go
  4. select * into t1
  5. from t
  6. create index idx_t1_idx1 on t1(i)
  7. go
  8. if exists(select * from sys.tables where name = 't2')
  9. drop table t2
  10. go
  11. select * into t2
  12. from t

7、对t1表进行删除操作,一次删除1000个数,每个数有64条,所以每次删除64000条。共删除1000次,所以删除640000条记录,总耗时82秒


  1. dbcc dropcleanbuffers
  2. go
  3. declare @i int = 20000;
  4. declare @start_time datetime;-- = getdate();
  5. while @i <30000
  6. begin
  7. set @start_time = GETDATE();
  8. delete from t1 where I>=@i and i<=@i + 999
  9. set @i += 1000
  10. select DATEDIFF(second,@start_time,getdate())
  11. end

8、删除t2表的数据,耗时44秒


  1. delete from t2
  2. where I>= 20000 and i<30000

通过上面的测试发现:

1、在大量插入操作时,在完成操作后再提交,比每次插入操作后马上就提交,效率要高。

2、在删除大量数据时,就算运用索引,甚至同时运用索引和分批操作,效率也不如不用索引,直接通过表扫描删除来的高。

但表扫描的问题是会锁住整个表,阻塞其他事务,导致系统业务大面积瘫痪。

所以,虽然通过直接的删除方法会速度快,但如果通过索引和分批处理,那么只会锁定需要删除的一批数据,而其他的数据则不会锁定,那么导致的阻塞问题就小多了。

3、所以结合上面的2点,当大批量操作时,如果最后提交,那么整个操作效率更高,但是可能会导致阻塞的问题,因为不及时提交,会导致其他事务都被阻塞。

同样的,通过直接删除效率可能更高,但会锁表,会导致严重的阻塞问题,而通过索引和分批处理,虽然效率不是太高,但可以分批处理,相当于分批提交,而每一批都通过索引,只锁住需要处理的记录,而其他的记录都不会锁住,那么就不太会导致阻塞的问题。

所以,大批量的删除操作,如果通过全表扫描,适合在晚上系统比较空闲的维护时间内进行;而如果一定要在白天执行,那么可以考虑通过索引和分批处理,来减少阻塞的问题,但还是会对系统产生一定的影响,特别是内存方面。

发布了416 篇原创文章 · 获赞 135 · 访问量 94万+

【SQL Server性能优化】删除大量数据的方法比较的更多相关文章

  1. SQL Server 性能优化之——系统化方法提高性能

    SQL Server 性能优化之——系统化方法提高性能 阅读导航 1. 概述 2. 规范逻辑数据库设计 3. 使用高效索引设计 4. 使用高效的查询设计 5. 使用技术分析低性能 6. 总结 1. 概 ...

  2. SQL SERVER性能优化综述

    SQL SERVER性能优化综述 一个系统的性能的提高,不单单是试运行或者维护阶段的性能调优的任务,也不单单是开发阶段的事情,而是在整个软件生命周期都需要注意,进行有效工作才能达到的.所以我希望按照软 ...

  3. SQL Server 性能优化之RML Utilities:快速入门(Quick Start)(1)

      SQL Server 性能优化之RML Utilities:快速入门(Quick Start)(1) 安装Quick Start工具 RML(Replay Markup Language)是MS ...

  4. SQL Server性能优化(6)查询语句建议

    1. 如果对数据不是工业级的访问(允许脏读),在select里添加 with(nolock) ID FROM Measure_heat WITH (nolock) 2. 限制结果集的数据量,如使用TO ...

  5. 【SQL Server性能优化】运用SQL Server的全文检索来提高模糊匹配的效率

    原文:[SQL Server性能优化]运用SQL Server的全文检索来提高模糊匹配的效率 今天去面试,这个公司的业务需要模糊查询数据,之前他们通过mongodb来存储数据,但他们说会有丢数据的问题 ...

  6. SQL Server 性能优化(一)——简介

    原文:SQL Server 性能优化(一)--简介 一.性能优化的理由: 听起来有点多余,但是还是详细说一下: 1.节省成本:这里的成本不一定是钱,但是基本上可以变相认为是节省钱.性能上去了,本来要投 ...

  7. SQL Server性能优化与管理的艺术 附件下载地址

    首先感谢读者们对鄙人的支持,购买了<SQL Server性能优化与管理的艺术>,由于之前出版社的一些疏忽,附件没有上传成功,再次本人深表歉意. 请需要下载附件的读者从下面链接下载,谢谢: ...

  8. 清空SQL Server数据库中所有表数据的方法(转)

    清空SQL Server数据库中所有表数据的方法 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可能陷入 ...

  9. 清空SQL Server数据库中所有表数据的方法

    原文:清空SQL Server数据库中所有表数据的方法 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可 ...

随机推荐

  1. arcgis python 布局中所有元素信息报告

    # Author: ESRI # Date: July 5, 2010 # Version: ArcGIS 10.0 # Purpose: This script generates a report ...

  2. openstack 基镜像展开过程

  3. 原生JavaScript实现函数的防抖和节流

    原生JavaScript实现函数的防抖和节流 参考:https://www.jianshu.com/p/c8b86b09daf0 想详细了解的直接戳上面链接了,讲得非常清楚.下面只给代码和我自己写的注 ...

  4. 快速查看MySQL数据库的版本号

    1.利用dos命令连接数据库后即有版本号信息 2.利用navicat连接mysql的客户端工具也是可以查看的 直接选中一个连接,然后右键-连接信息查看 3.利用专门的mysql命令查看 4.直接查看咱 ...

  5. Mybase解决保存文件后再打开不能修改编辑

    1.问题复现 2.解决方式 3.可以修改编辑

  6. OpenStack Magnum项目简介

    1 项目简介 Magnum是OpenStack中一个提供容器集群部署的服务. Magnum是一个Pass层的OpenStack项目. Magnum使用Heat部署一个包含Docker和Kubernet ...

  7. 123457123457#0#-----com.threeapp.PaoPaoLong01-----泡泡龙大作战01

    com.threeapp.PaoPaoLong01-----泡泡龙大作战01

  8. Windows server 2008 R2 桌面服务器管理器打开提示:试图引用不存在的令牌

    来源:https://social.technet.microsoft.com/Forums/zh-CN/90f376a3-2b52-46c1-be34-4a2dbf4fdea2/winserver2 ...

  9. 在node.js中使用Set

    var set = new Set(); set.add(1); console.log("test1 : " + set.has(1) + " ; " + s ...

  10. JS 回车提交,兼容IE、火狐、Opera、Chrome、Safari……

    1.JavaScript 方法: <script>      document.onkeydown=function(event){          e = event ? event  ...