原文:【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. 学习笔记——C++编程cin测试记录

    cin读取输入流,遇到空格会暂停,下次继续读入剩下的,+++. #include <iostream> using namespace std; int main() { cout< ...

  2. 一个Flask应用运行过程剖析

    相信很多初学Flask的同学(包括我自己),在阅读官方文档或者Flask的学习资料时,对于它的认识是从以下的一段代码开始的: from flask import Flask app = Flask(_ ...

  3. docker之redis使用

    #拉取redis > docker pull redis:latest latest: Pulling from library/redis 8d691f585fa8: Pull complet ...

  4. Yarn简单介绍及内存配置

    本文出自:http://blog.chinaunix.net/uid/28311809/abstract/1.html 在这篇博客中,主要介绍了Yarn对MRv1的改进,以及Yarn简单的内存配置和Y ...

  5. Tips for vcpkg

    概述 vcpkg是微软开发的在Windows, Linux和MacOS平台管理C/C++库的开源工具. 快速开始 要求 使用vcpkg需满足如下条件: Windows 10, 8.1, 7, Linu ...

  6. migrate设置

    migrate配置 进入项目manage所在的目录中执行如下命令,否则会报错:no such table: django_session 进入cmd 输入盘符比如:E: 切换目录 cd E:\prog ...

  7. topK问题

    概述 在N个乱序数字中查找第K大的数字,时间复杂度可以减小至O(N). 可能存在的限制条件: 要求时间和空间消耗最小.海量数据.待排序的数据可能是浮点型等. 方法 方法一 对所有元素进行排序,之后取出 ...

  8. iOS-UIButton分类扩展(封装)

    UIButton+BackgroundColor.h #import <UIKit/UIKit.h> @interface UIButton (BackgroundColor) - (vo ...

  9. 如何理解AWS 网络,如何创建一个多层安全网络架构

    目录 一.要求 网络架构图 网络各组件关系 二.操作步骤 2.1.网络设置 2.2.安全设置 2.3.创建实例 三.费用 3.1.NAT 网关费用 一.要求 创建一个三层网络架构,服务器只能通过跳板机 ...

  10. Mac OS X下把 /etc/sudoers 写错了怎么办?(转载https://blog.csdn.net/robertsong2004/article/details/53725285)

    重要的事情先说一下,首先为了回避这个问题,一定要用 visudo 来改 /etc/sudoers 文件. 问题描述: 1. 用  sudo vi 直接改 /etc/sudoers 并覆盖原文件. 2. ...