首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

怎么解决执行sql存储过程(大数据量复杂的sql计算操作)时,不影响用户使用

2013-09-05 
如何解决执行sql存储过程(大数据量复杂的sql计算操作)时,不影响用户使用在一个系统中,需要执行一个存储过

如何解决执行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如何设置,这个也的确有点虚,哪怕是什么最佳实践,也 往往不会通用,我那个只是举个例子而已,重点是你找出瓶颈
[解决办法]
引用:

我找到原因了,不是因为锁表问题引起的,我使用监视器发现没有锁表情况,我一个地方插入数据进行循环使用的是表变量,而不是临时表,但是我插入的数据量有10000条,我改成临时表操作后,就不会出现上面的问题,我想应该是数据库的内存被耗光了,大家觉得有没有这个可能。

#1.1W条记录不是问题。表使用完,你会DELETE Tablename来清空吧?
#2.如果楼主,改成临时表就立马好,改成表变量,就立马不好。内存缺少的可能性比较大。当然,楼主监控一下,出问题时的资源使用情况,便知。一般内存的缺少往往会伴随CPU的升高和磁盘IO增大(内存和磁盘调度)
[解决办法]
引用:
Quote: 引用:

听过一个人说他测试过,只要select count(1) from 表 一次,这些数据就会载入缓存,当然,前提是你的内存足够

这个测试准确吗,我执行select Count(1) from 表,表数据有80多W,总共才使用16K内存,我是通过活动监视器那边查看执行语句所使用的内存
那个是语句的内存,不是数据占用的内存,不过如果你可以测试,可以做个简单的实验:
1、清空缓存
2、select count(1) from 表
3、再select 一部分甚至全部数据,记得打开set statistics io on ,看看是否只有逻辑读我不保证这个方法是准确的。
[解决办法]
这个我觉得你很难监控,只能看到个大概。内存这块太大了,我也不怎么熟悉

热点排行