SQLServer 存儲過程調優小結


公司服務器崩了,很多測試環境用不了,弄了一個生產庫還原到本地,調了下統計分析系統的一些存儲過程:

場景:首頁一進去就加載七個報表,而且是實時計算的。。。不光耗資源,還會鎖住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,不然完全感覺不出來。服務器的性能雖然也比較緊張,但並發量不大的話也看不出區別。就是數據庫一差能差很遠,隨時卡死卡崩喜聞樂見。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM