【SQL Server性能优化】大量数据删除的方法比较
2013-08-16 19:15
567 查看
实验代码:
通过上面的测试发现:
1、在大量插入操作时,在完成操作后再提交,比每次插入操作后马上就提交,效率要高。
2、在删除大量数据时,就算运用索引,甚至同时运用索引和分批操作,效率也不如不用索引,直接通过表扫描删除来的高。
但表扫描的问题是会锁住整个表,阻塞其他事务,导致系统业务大面积瘫痪。
所以,虽然通过直接的删除方法会速度快,但如果通过索引和分批处理,那么只会锁定需要删除的一批数据,而其他的数据则不会锁定,那么导致的阻塞问题就小多了。
3、所以结合上面的2点,当大批量操作时,如果最后提交,那么整个操作效率更高,但是可能会导致阻塞的问题,因为不及时提交,会导致其他事务都被阻塞。
同样的,通过直接删除效率可能更高,但会锁表,会导致严重的阻塞问题,而通过索引和分批处理,虽然效率不是太高,但可以分批处理,相当于分批提交,而每一批都通过索引,只锁住需要处理的记录,而其他的记录都不会锁住,那么就不太会导致阻塞的问题。
所以,大批量的删除操作,如果通过全表扫描,适合在晚上系统比较空闲的维护时间内进行;而如果一定要在白天执行,那么可以考虑通过索引和分批处理,来减少阻塞的问题,但还是会对系统产生一定的影响,特别是内存方面。
本文出自 “探索SQLServer” 博客,请务必保留此出处http://yupeigu.blog.51cto.com/3323001/1368128
use master go if exists(select * from sys.databases where name = 'test') drop database test go --创建数据库 create database test if exists(select * from sys.tables where name = 't') drop table t go --创建表t 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)); --添加100000条记录,消耗9秒 declare @i int; declare @sql varchar(1000); set @i = 1 set @sql = ''; begin tran while @i <= 100000 begin set @sql = 'insert into t(i) values(' + cast(@i as varchar) +')' exec(@sql) set @i = @i + 1 end commit tran /* --添加100000条记录,消耗43秒 declare @i int; declare @sql varchar(1000); set @i = 1 set @sql = ''; while @i <= 100000 begin set @sql = 'insert into t(i) values(' + cast(@i as varchar) +')' begin tran exec(@sql) --没执行一次就提交一次,效率较差 commit tran set @i = @i + 1 end */ --消耗1分38秒 insert into t select * from t go 6 create index idx_t_idx1 on t(i) --6400000条记录 select count(*) from t -------------------------------------------------------------- /* --避免笔记本或台式机,由于用太多内存导致死机 sp_configure 'show advanced option',1 go reconfigure go sp_configure 'max server memory (MB)',3584 go reconfigure go */ 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) dbcc dropcleanbuffers --1.一次删除1000个数,每个数有64条,所以每次删除64000条 --一共删除1000次,所以删除640000条记录 --总耗时82秒 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 --------------------------------------------------------- if exists(select * from sys.tables where name = 't2') drop table t2 go select * into t2 from t dbcc dropcleanbuffers --2.直接删除 --耗时44秒 delete from t2 where I>= 20000 and i<30000
通过上面的测试发现:
1、在大量插入操作时,在完成操作后再提交,比每次插入操作后马上就提交,效率要高。
2、在删除大量数据时,就算运用索引,甚至同时运用索引和分批操作,效率也不如不用索引,直接通过表扫描删除来的高。
但表扫描的问题是会锁住整个表,阻塞其他事务,导致系统业务大面积瘫痪。
所以,虽然通过直接的删除方法会速度快,但如果通过索引和分批处理,那么只会锁定需要删除的一批数据,而其他的数据则不会锁定,那么导致的阻塞问题就小多了。
3、所以结合上面的2点,当大批量操作时,如果最后提交,那么整个操作效率更高,但是可能会导致阻塞的问题,因为不及时提交,会导致其他事务都被阻塞。
同样的,通过直接删除效率可能更高,但会锁表,会导致严重的阻塞问题,而通过索引和分批处理,虽然效率不是太高,但可以分批处理,相当于分批提交,而每一批都通过索引,只锁住需要处理的记录,而其他的记录都不会锁住,那么就不太会导致阻塞的问题。
所以,大批量的删除操作,如果通过全表扫描,适合在晚上系统比较空闲的维护时间内进行;而如果一定要在白天执行,那么可以考虑通过索引和分批处理,来减少阻塞的问题,但还是会对系统产生一定的影响,特别是内存方面。
本文出自 “探索SQLServer” 博客,请务必保留此出处http://yupeigu.blog.51cto.com/3323001/1368128
相关文章推荐
- 【SQL Server性能优化】删除大量数据的方法比较
- ArcEngine,C#删除数据几种方法和性能比较
- [转]不同版本的SQL Server之间数据导出导入的方法及性能比较
- ArcEngine数据删除几种方法和性能比较
- ArcEngine数据删除几种方法和性能比较[转]
- ArcEngine数据删除几种方法和性能比较
- 不同版本的SQL Server之间数据导出导入的方法及性能比较
- MySQL大量数据插入各种方法性能分析与比较
- ArcEngine,C#数据删除几种方法以及性能比较
- 不同版本的SQL Server之间数据导出导入的方法及性能比较
- ArcEngine数据删除几种方法和性能比较【转载】
- ArcEngine数据删除几种方法和性能比较
- ArcEngine数据删除几种方法和性能比较【转载】
- ArcEngine数据删除几种方法和性能比较【转载】
- 【20090524-01】ArcEngine数据删除几种方法和性能比较【转载】
- ArcEngine数据删除几种方法和性能比较
- 不同版本的SQL Server之间数据导出导入的方法及性能比较
- ArcEngine数据删除几种方法和性能比较 转载的
- ArcEngine数据删除几种方法和性能比较
- 不同版本的SQL Server之间数据导出导入的方法及性能比较