原文:【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 使用光标和内存中的要素类将数据加载到要素集 学习:http://zhihu.esrichina.com.cn/article/634

    学习:http://zhihu.esrichina.com.cn/article/634使用光标和内存中的要素类将数据加载到要素集 import arcpy arcpy.env.overwriteOu ...

  2. MAC常用快捷键 基本常用的都整理在这里了

    写在前面Mac系统中有几个比较特殊的功能键,和Win系统的区别也主要在这里比如在Win系统中我们常用的Ctrl键,在Mac系统中对应的不是长得比较像的Cnotrol,而是Command键,貌似也是Ma ...

  3. sql 从服务器取消主从复制

    mysql>change master to master_host='' mysql>stop slave;reset slave;

  4. Borg、Omega和Kubernetes:谷歌十几年来从这三个容器管理系统中得到的经验教训 原创: 韩佳瑶 译 Docker 2016-03-23Borg、Omega和Kubernetes:谷歌十几年来从这三个容器管理系统中得到的经验教训 原创: 韩佳瑶 译 Docker 2016-03-23

    Borg.Omega和Kubernetes:谷歌十几年来从这三个容器管理系统中得到的经验教训 原创: 韩佳瑶 译 Docker 2016-03-23

  5. el-table的type="selection"的使用

    场景:el-table,type="selection"时,重新请求后,设置列表更新前的已勾选项 踩坑:在翻页或者changPageSize之后,table的data会更新,之前勾 ...

  6. OpenSL ES: OpenSL ES 简介

    1. OpenSL ES 是什么 OpenSL ES (Open Sound Library for Embedded Systems)是无授权费.跨平台.针对嵌入式系统精心优化的硬件音频加速API. ...

  7. Pattern 和 Matcher

    作用:应用这个 Pattern 和 Matcher 可以完成字符串获取功能 使用: // 获取模式器对象 Pattern p = Pattern.compile("a*b") ; ...

  8. 27flutter日期 时间组件flutter_cupertino_date_picker的使用

    pubspec.yaml flutter_cupertino_date_picker: ^ DatePicker.dart import 'package:date_format/date_forma ...

  9. 本地git仓库推送到服务器自建的git仓库实现目录文件同步教程

    首先,先在服务器上安装git,如果有git的话就不用走这一步了 yum安装git [root@iZuf6fazwjb6lb3z82smzoZ ~]# cd src/ [root@iZuf6fazwjb ...

  10. esxi 配置 交换主机 虚拟机交换机 linux centos 配置双网卡

    最近手里的项目网络环境是 192.168.199.1 直接到防火墙 192.168.1.x 是内网网段 走到 防火墙下的一个三层交换机 现在需要将内网的三台服务器端口映射出去,需要到防火墙去做映射,防 ...