如何解决执行sql存储过程(大数据量复杂的sql计算操作)时,不影响用户使用
在一个系统中,需要执行一个存储过程(里面封装多个具体业务模块的存储过程组合)进行大数据量的复杂计算过程。由于该执行过程耗时较长,因此每当一执行这个操作时,前台的功能模块就无法及时响应,被阻塞住。其中对涉及计算的存储过程进行过优化处理,但是还是无法达到理想的效果。思考很久,想过很多方案,一直无法解决这个问题,困扰了我很久,现想请论坛中sql高手提供点建设性的解决方案,谢谢,分绝不少给。
我曾经想过的通过wait delay 方式间隔执行计算过程,避免长期锁住计算的表,阻塞住其他正常用户的访问,但是不是很有效果。
说明:系统涉及到计算的表的功能,计算时无法正常访问,其他功能可以正常访问!
------解决方案--------------------还是优化sql吧,先找出到底是哪里影响了性能,那后在进行优化。
两种方法找出在SP中影响性能最多的SQL
1 使用Profile监控存储过程,包含存储过程中的SQL语句。
2 直接更改SP,没执行一个逻辑保存一笔时间记录,然后查找出时间最长的计算逻辑
找出语句后再优化就可以了。
------解决方案--------------------with nolock并不能从根源上解决性能问题,还有可能带来很多一致性的问题,当然在一些实在没办法的情景下,还是可以酌情使用。对于业务逻辑很复杂的运算,可以从拆分的方法,只要前后关联并不非常密切,其实可以拆成多个存储过程来实现,可以在存储过程里面再调用存储过程,这样可以一定程度下缓解一个大事务所带来的锁、阻塞甚至死锁问题。如果不懂优化,即使oracle也很难处理得很好。优化你的语句是非常重要的,至于其他方面,需要定位瓶颈才行,比如如果你的语句要用到很多且很大的临时表,但是tempdb又只有那么一点,频繁增长会带来很大的I/O压力,而且如果物理磁盘I/O性能本来就很差,那压力更大。如何定位瓶颈,工具有很多:DMO、profiler、waittype甚至xevent等等,都可以使用。当然重要的还是改写语句,把你的瓶颈逐步或者一次性解决,没有定位之前,所有建议都仅仅是猜想。
------解决方案--------------------首先,整个存储过程是封装到一个事务中吗?如果不是,那就可以分步执行。是,则需要重新考虑你的业务逻辑。
硬件提升对性能的增长是有一个瓶颈的,
索引,分区,语句优化也会有一个瓶颈,
当数据库设计差的时候,这些瓶颈更容易暴露,带来的损害也最大。
------解决方案--------------------
#1.大事务,避免使用
#2.业务允许的情况下,加WITH(NOLOCK)
#3.找出性能瓶颈,修改索引和SQL和从逻辑上进行优化
------解决方案--------------------把那些表转为历史表,操作的时候在历史表里面,那些问题还是问题吗,还有就是一个存储过程里面嵌套其他存储过程,最好只有主存储过程中有事务,其它里面不要出现事务。防止假死。
------解决方案--------------------
#1.如果临时表,只用到一次,想办法不用临时表,直接更新。如果会多次使用,可以加索引后,再使用。
#2.异常在其它机器上也会出现吗,试试。
总之,楼主若想解决问题,还得把代码让大家看看,否则,有点儿空
------解决方案--------------------tempdb如何设置,这个也的确有点虚,哪怕是什么最佳实践,也 往往不会通用,我那个只是举个例子而已,重点是你找出瓶颈
------解决方案--------------------