概述今天下午
优化了一个存储过程,通过sys.dm_exec_query_stats和sys.dm_exec_sql_text() 定位到的,发现运行次数虽然很少,但是每次却长达上千万毫秒的cpu消耗,但实际执行虽然时间比较久,却也不过几十分钟而已,不知道是不是SQLServer系统
性能视图的缺陷。 既然有问题那就找吧 这是一个存储过程,类似于 create procedure sp_exec_task 今天下午优化了一个存储过程,通过sys.dm_exec_query_stats和sys.dm_exec_sql_text() 定位到的,发现运行次数虽然很少,但是每次却长达上千万毫秒的cpu消耗,但实际执行虽然时间比较久,却也不过几十分钟而已,不知道是不是sqlServer系统性能视图的缺陷。 既然有问题那就找吧 这是一个存储过程,类似于 create procedure sp_exec_task as declare cursor cur_test for select * from tableA begin open cur_test fetch cur_test into ... WHILE @@FETCH_STATUS=0 BEGIN if true update tableB where ID=tableA.ID and other_cond else update tableB where ID=tableA.ID and other_cond if true update tableC where ID=tableA.ID and other_cond else update tableC where ID=tableA.ID and other_cond fetch cur_test into ... end CLOSE cur_test DEALLOCATE cur_test end 怎么分析呢? 1、开始的时候是让游标空循环,发现一共1万多条记录,空循环时间基本为0 2、再次把所有的DML语句转化为SELECT,并记录每个步骤的运行时间和一次完整游标的循环时间 最后循环中变为 BEGIN print 'step 1'+convert(varchar,109,getdate() select * from tableB where ID=tableA.ID and other_cond print 'step 1'+convert(varchar,getdate() select * from tableC where ID=tableA.ID and other_cond END 通过上百次的循环测试,发现每次循环大概需要60毫秒,100次的花就是6秒,10000次可不就是10分钟 3、检查了一下游标循环中用的表和where条件,发现选择性不错,就添加索引,再次安装上面的办法进行测试 这次是单次循环0~1毫秒,100次大概是1秒,10000次还是需要1分多钟的 4、1分多钟是可以忍受的,干脆直接测完吧,运行过程中,不断发现内存消耗极大,很快居然耗光了内存 5、添加了SET NOCOUNT ON之类的,运行后还是内存暴增 6、后来思考了一下是不是select * from tableB的不断刷新导致的,直接修改为 select top 1 @tt=tt from tableB where ID=tableA.ID and other_cond 这样就不会持续刷新屏幕了 7、运行后,果然只需要短短的4秒钟。 总结: 其实在数据库中与性能相关的,无论是耗cpu还是耗内存还是耗硬盘还是锁的问题,分析到最后,95%以上都与sql和索引相关 首先要找到问题,才能谈到分析问题,分析问题就在于多实践,而实践在于尽量屏蔽与问题无关的外界因素。 总结
以上是内存溢出为你收集整理的SQLServer性能优化一则小实例(2010-07-22)全部内容,希望文章能够帮你解决SQLServer性能优化一则小实例(2010-07-22)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
评论列表(0条)