公司服务器崩了,很多测试环境用不了,弄了一个生产库还原到本地,调了下统计分析系统的一些存储过程:
场景:首页一进去就加载七个报表,而且是实时计算的。。。不光耗资源,还会锁住AJAX,串行一个个执行这七个存储过程,导致其它的AJAX执行不了(表现在点击其它子菜单无响应,要等前面AJAX用完了才会轮到后面)
1、固化数据、缓存什么的,先不考虑,还是按原样先动态实时取首页吧,接手过来的项目先不急着翻新,先看能否花半天一天优化。
2、按前几天学的在控制器上设置Session的Readonly,刷新首页发现死锁。。。而且是每次必死锁
3、检查存储过程,发现里面都有两句UPDATE全库的一个字段,如果是NulL则取另一个值。这个没必要每次查询都去全库更新,会锁表,也不可能存在这么多异常数据,这种数据修正的,放在每晚同步时处理就好了,去掉后不再死锁。
4、并行后,速度反正不如原先串行的。。。串行的每个执行只要1~3秒(虽然也不短),但整体下来还好,一个个等它轮圈,二十秒左右也全部加载完了。但并行后,每个都要花掉10~20秒左右。。。翻了好几倍
5、复制出来执行,一个个又恢复到1~3秒,怀疑是并发引起,又不好重现并发场景,就把sql窗口缩小,屏幕上并排摆了7个,一个个快速切换到窗口用快捷键执行,这样也重现出了速度慢的情况。
6、观察存储过程,有两张大表(几十万),没加索引。加完索引后,效果不明显。
7、再观察用到原表很少,几乎都是先把原表数据SELECT * INTO至一个临时表。有些过滤条件都过滤不了多少,几乎相当于原表全进内存(临时表)了
8、把SELECT * 改为只要用到的4个字段,效果不明显
9、发现一个大表写了两次,而第二次的临时表后面完全没用到(Ctrl + F搜索),去掉后效果显著,正常了。
10、初步怀疑是大表进内存太多了,刚好到一个临界值,再加一张大表就会触发tempdb和磁盘进行大量IO或页查找之类(不懂底层原理。。。)。临时表不是万能药,只是数据量少时用临时表才有效,几十万的数据进临时表有时适得其反。
11、临时表和真实表的区别,如果体量差不多,临时表没有索引,没法优化,还不如有索引的真实表。存储过程是支持给临时表加索引。
今天一开始也是这样尝试给临时表加索引的,但索引只用一次,效率反而比不上不加。因为加索引也是要时间的,加完只执行一两段就结束了,加索引所耗的时间还没赚回来。
12、期间也怀疑了【参数嗅探】,即要在存储过程里再定义个内部变量去接收传进来的参数。试了无效,且存储过程里面大量拼接字符串,这种拼字符串也是很影响分析器分析的。
性能优化,主要还是集中在数据库这里。能差好几倍,现在PC、服务器性能都不错了,前端的Js解析,除非循环太大或是有超大table,不然完全感觉不出来。服务器的性能虽然也比较紧张,但并发量不大的话也看不出区别。就是数据库一差能差很远,随时卡死卡崩喜闻乐见。
总结以上是内存溢出为你收集整理的SQLServer 存储过程调优小结全部内容,希望文章能够帮你解决SQLServer 存储过程调优小结所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)