SQLServer 存储过程调优小结

你说的曾经没有我的故事 提交于 2020-02-19 01:55:42

公司服务器崩了,很多测试环境用不了,弄了一个生产库还原到本地,调了下统计分析系统的一些存储过程:

场景:首页一进去就加载七个报表,而且是实时计算的。。。不光耗资源,还会锁住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,不然完全感觉不出来。服务器的性能虽然也比较紧张,但并发量不大的话也看不出区别。就是数据库一差能差很远,随时卡死卡崩喜闻乐见。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!