【SQL Server性能优化】删除大量数据的方法比较
原文:【SQL Server性能优化】删除大量数据的方法比较
如果你要删除表中的大量数据,这个大量一般是指删除大于10%的记录,那么如何删除,效率才会比较高呢? 而如何删除才会对系统的影响相对较小呢?
下面先做一个实验,然后对这个实验的结果进行分析,然后得出结论。
1、创建数据库
-
use master
-
go
-
-
if exists(select * from sys.databases where name = 'test')
-
drop database test
-
go
-
-
create database test
-
go
2、创建表
-
use test
-
go
-
-
-
if exists(select * from sys.tables where name = 't')
-
drop table t
-
go
-
-
create table t(i int,v varchar(100) default replicate('a',100)
-
,vv varchar(100) default replicate('a',100),
-
vvv varchar(100) default replicate('a',100));
3、插入数据
用下面的代码添加100000条记录,消耗9秒:
-
declare @i int;
-
-
set @i = 1
-
-
begin tran
-
-
while @i <= 100000
-
begin
-
insert into t(i) values(@i)
-
-
set @i = @i + 1
-
end
-
-
commit tran
而如果用下面的代码,添加100000条记录,消耗43秒:
-
declare @i int;
-
-
set @i = 1
-
-
while @i <= 100000
-
begin
-
begin tran
-
insert into t(i) values(@i) --没执行一次就提交一次,效率较差
-
commit tran
-
-
set @i = @i + 1
-
end
重复插入数据,消耗1分38秒
-
insert into t
-
select *
-
from t
-
go 6
最后总共插入了640万条数据。
4、建立索引
create index idx_t_idx1 on t(i)
5、进行如下设置,是为了预防SQL Server使用太多内存,而导致死机
-
sp_configure 'show advanced option',1
-
go
-
reconfigure
-
go
-
-
sp_configure 'max server memory (MB)',3584
-
go
-
reconfigure
-
go
6、把上面创建的表t数据,复制成t1和t2两个表,对t1表建立索引
-
if exists(select * from sys.tables where name = 't1')
-
drop table t1
-
go
-
-
select * into t1
-
from t
-
-
create index idx_t1_idx1 on t1(i)
-
go
-
-
-
if exists(select * from sys.tables where name = 't2')
-
drop table t2
-
go
-
-
select * into t2
-
from t
7、对t1表进行删除操作,一次删除1000个数,每个数有64条,所以每次删除64000条。共删除1000次,所以删除640000条记录,总耗时82秒
-
dbcc dropcleanbuffers
-
go
-
-
declare @i int = 20000;
-
declare @start_time datetime;-- = getdate();
-
-
while @i <30000
-
begin
-
-
set @start_time = GETDATE();
-
-
delete from t1 where I>=@i and i<=@i + 999
-
-
set @i += 1000
-
select DATEDIFF(second,@start_time,getdate())
-
-
end
8、删除t2表的数据,耗时44秒
-
delete from t2
-
where I>= 20000 and i<30000
通过上面的测试发现:
1、在大量插入操作时,在完成操作后再提交,比每次插入操作后马上就提交,效率要高。
2、在删除大量数据时,就算运用索引,甚至同时运用索引和分批操作,效率也不如不用索引,直接通过表扫描删除来的高。
但表扫描的问题是会锁住整个表,阻塞其他事务,导致系统业务大面积瘫痪。
所以,虽然通过直接的删除方法会速度快,但如果通过索引和分批处理,那么只会锁定需要删除的一批数据,而其他的数据则不会锁定,那么导致的阻塞问题就小多了。
3、所以结合上面的2点,当大批量操作时,如果最后提交,那么整个操作效率更高,但是可能会导致阻塞的问题,因为不及时提交,会导致其他事务都被阻塞。
同样的,通过直接删除效率可能更高,但会锁表,会导致严重的阻塞问题,而通过索引和分批处理,虽然效率不是太高,但可以分批处理,相当于分批提交,而每一批都通过索引,只锁住需要处理的记录,而其他的记录都不会锁住,那么就不太会导致阻塞的问题。
所以,大批量的删除操作,如果通过全表扫描,适合在晚上系统比较空闲的维护时间内进行;而如果一定要在白天执行,那么可以考虑通过索引和分批处理,来减少阻塞的问题,但还是会对系统产生一定的影响,特别是内存方面。
【SQL Server性能优化】删除大量数据的方法比较的更多相关文章
- SQL Server 性能优化之——系统化方法提高性能
SQL Server 性能优化之——系统化方法提高性能 阅读导航 1. 概述 2. 规范逻辑数据库设计 3. 使用高效索引设计 4. 使用高效的查询设计 5. 使用技术分析低性能 6. 总结 1. 概 ...
- SQL SERVER性能优化综述
SQL SERVER性能优化综述 一个系统的性能的提高,不单单是试运行或者维护阶段的性能调优的任务,也不单单是开发阶段的事情,而是在整个软件生命周期都需要注意,进行有效工作才能达到的.所以我希望按照软 ...
- SQL Server 性能优化之RML Utilities:快速入门(Quick Start)(1)
SQL Server 性能优化之RML Utilities:快速入门(Quick Start)(1) 安装Quick Start工具 RML(Replay Markup Language)是MS ...
- SQL Server性能优化(6)查询语句建议
1. 如果对数据不是工业级的访问(允许脏读),在select里添加 with(nolock) ID FROM Measure_heat WITH (nolock) 2. 限制结果集的数据量,如使用TO ...
- 【SQL Server性能优化】运用SQL Server的全文检索来提高模糊匹配的效率
原文:[SQL Server性能优化]运用SQL Server的全文检索来提高模糊匹配的效率 今天去面试,这个公司的业务需要模糊查询数据,之前他们通过mongodb来存储数据,但他们说会有丢数据的问题 ...
- SQL Server 性能优化(一)——简介
原文:SQL Server 性能优化(一)--简介 一.性能优化的理由: 听起来有点多余,但是还是详细说一下: 1.节省成本:这里的成本不一定是钱,但是基本上可以变相认为是节省钱.性能上去了,本来要投 ...
- SQL Server性能优化与管理的艺术 附件下载地址
首先感谢读者们对鄙人的支持,购买了<SQL Server性能优化与管理的艺术>,由于之前出版社的一些疏忽,附件没有上传成功,再次本人深表歉意. 请需要下载附件的读者从下面链接下载,谢谢: ...
- 清空SQL Server数据库中所有表数据的方法(转)
清空SQL Server数据库中所有表数据的方法 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可能陷入 ...
- 清空SQL Server数据库中所有表数据的方法
原文:清空SQL Server数据库中所有表数据的方法 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可 ...
随机推荐
- Docker学习知识图
这个图更能明白他们之间的关系 文章来源:外星人来地球 欢迎关注,有问题一起学习欢迎留言.评论
- 获取用户当前位置信息的两种方法——H5、微信
在之前的 调用百度地图API的总结 中获取当前位置信息我用的是 H5 ,其实微信也提供了获取用户地理位置的方法,现将这两种方法都贴出来,看情况选择使用. 一.H5 获取当前地理位置得到经纬度 // H ...
- pom.xml中properties作用
可以在properties下声明相应的版本信息,然后在dependency下引用的时候用${spring-version}就可以引入该版本jar包了 <properties> <sp ...
- LightGBM建模
LightGBM 1.读取csv数据并指定参数建模 # coding: utf-8 import json import lightgbm as lgb import pandas as pd fro ...
- C#中 Dictionary<>的使用及注意事项
1,如果在主体代码中使用,直接在初始化中生成就行 2如果在其他层,比如逻辑层,要注意在事件内部定义,在外部的话,重复调用就会提示“”“已经定义了相同的KEY”,见例子 (例子是转的) Dictiona ...
- angular中子组件通过@Output 触发父组件的方 法
1. 子组件引入 Output 和 EventEmitter import { Component, OnInit ,Input,Output,EventEmitter} from '@angular ...
- requests与urllib.request
requests很明显,在写法上与urllib.request不同,前者多一个 S.导入包时:import requestsimport urllib.requesturllib.request请求模 ...
- python mysql使用问题
(deeplearning2) userdeMBP:ageAndGender user$ python Python |Anaconda, Inc.| ( , ::) [GCC Compatible ...
- osg RTT 多相机-局部放大镜
#ifdef _WIN32 #include <Windows.h> #endif // _WIN32 #include<iostream> #include <osgV ...
- React vs. Angular vs. Vue
原文连接 历史 React是一个用于构建Web应用程序UI组件的JavaScript库. React由Facebook维护,许多领先的科技品牌在其开发环境中使用React. React被Faceboo ...