SQLServer效能優化一則小例項(2010-07-22)
今天下午優化了一個儲存過程,通過sys.dm_exec_query_stats和sys.dm_exec_sql_text() 定位到的,發現執行次數雖然很少,但是每次卻長達上千萬毫秒的cpu消耗,但實際執行雖然時間比較久,卻也不過幾十分鐘而已,不知道是不是SQLServer系統效能檢視的缺陷。
既然有問題那就找吧
這是一個儲存過程,類似於
create procedure sp_exec_task
as
declare cursor cur_test for select * from tableA
begin
open cur_test
fetch cur_test into ...
WHILE @@FETCH_STATUS=0
BEGIN
if true
update tableB where id=tableA.id and other_cond
else
update tableB where id=tableA.id and other_cond
if true
update tableC where id=tableA.id and other_cond
else
update tableC where id=tableA.id and other_cond
fetch cur_test into ...
end
CLOSE cur_test
DEALLOCATE cur_test
end
怎麼分析呢?
1、開始的時候是讓遊標空迴圈,發現一共1萬多條記錄,空迴圈時間基本為0
2、再次把所有的DML語句轉化為SELECT,並記錄每個步驟的執行時間和一次完整遊標的迴圈時間
最後迴圈中變為
BEGIN
print 'step 1'+convert(varchar,109,getdate()
select * from tableB where id=tableA.id and other_cond
print 'step 1'+convert(varchar,109,getdate()
select * from tableC where id=tableA.id and other_cond
END
通過上百次的迴圈測試,發現每次迴圈大概需要60毫秒,100次的花就是6秒,10000次可不就是10分鐘
3、檢查了一下游標迴圈中用的表和where條件,發現選擇性不錯,就新增索引,再次安裝上面的辦法進行測試
這次是單次迴圈0~1毫秒,100次大概是1秒,10000次還是需要1分多鐘的
4、1分多鐘是可以忍受的,乾脆直接測完吧,執行過程中,不斷發現記憶體消耗極大,很快居然耗光了記憶體
5、新增了SET NOCOUNT ON之類的,執行後還是記憶體暴增
6、後來思考了一下是不是select * from tableB的不斷重新整理導致的,直接修改為
select top 1 @tt=tt from tableB where id=tableA.id and other_cond
這樣就不會持續重新整理螢幕了
7、執行後,果然只需要短短的4秒鐘。
總結:
其實在資料庫中與效能相關的,無論是耗cpu還是耗記憶體還是耗硬碟還是鎖的問題,分析到最後,95%以上都與SQL和索引相關
首先要找到問題,才能談到分析問題,分析問題就在於多實踐,而實踐在於儘量遮蔽與問題無關的外界因素。
既然有問題那就找吧
這是一個儲存過程,類似於
create procedure sp_exec_task
as
declare cursor cur_test for select * from tableA
begin
open cur_test
fetch cur_test into ...
WHILE @@FETCH_STATUS=0
BEGIN
if true
update tableB where id=tableA.id and other_cond
else
update tableB where id=tableA.id and other_cond
if true
update tableC where id=tableA.id and other_cond
else
update tableC where id=tableA.id and other_cond
fetch cur_test into ...
end
CLOSE cur_test
DEALLOCATE cur_test
end
怎麼分析呢?
1、開始的時候是讓遊標空迴圈,發現一共1萬多條記錄,空迴圈時間基本為0
2、再次把所有的DML語句轉化為SELECT,並記錄每個步驟的執行時間和一次完整遊標的迴圈時間
最後迴圈中變為
BEGIN
print 'step 1'+convert(varchar,109,getdate()
select * from tableB where id=tableA.id and other_cond
print 'step 1'+convert(varchar,109,getdate()
select * from tableC where id=tableA.id and other_cond
END
通過上百次的迴圈測試,發現每次迴圈大概需要60毫秒,100次的花就是6秒,10000次可不就是10分鐘
3、檢查了一下游標迴圈中用的表和where條件,發現選擇性不錯,就新增索引,再次安裝上面的辦法進行測試
這次是單次迴圈0~1毫秒,100次大概是1秒,10000次還是需要1分多鐘的
4、1分多鐘是可以忍受的,乾脆直接測完吧,執行過程中,不斷發現記憶體消耗極大,很快居然耗光了記憶體
5、新增了SET NOCOUNT ON之類的,執行後還是記憶體暴增
6、後來思考了一下是不是select * from tableB的不斷重新整理導致的,直接修改為
select top 1 @tt=tt from tableB where id=tableA.id and other_cond
這樣就不會持續重新整理螢幕了
7、執行後,果然只需要短短的4秒鐘。
總結:
其實在資料庫中與效能相關的,無論是耗cpu還是耗記憶體還是耗硬碟還是鎖的問題,分析到最後,95%以上都與SQL和索引相關
首先要找到問題,才能談到分析問題,分析問題就在於多實踐,而實踐在於儘量遮蔽與問題無關的外界因素。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/6517/viewspace-668803/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 分享一個SQLite 效能優化例項SQLite優化
- JavaScript 前端效能優化小竅門例項彙總JavaScript前端優化
- 效能優化指南:效能優化的一般性原則與方法優化
- 淺談網頁基本效能優化規則小結網頁優化
- 如何讀懂火焰圖?+ 例項講解程式效能優化優化
- Spark效能調優——9項基本原則Spark
- sqlserver修改例項名稱SQLServer
- vue效能優化小結Vue優化
- 前端效能優化小結前端優化
- iOS效能優化系列篇之“優化總體原則”iOS優化
- 資料庫例項效能調優利器:Performance Insights資料庫ORM
- React效能優化:PureComponent的使用原則React優化
- 優化 WebView 的載入速度例項優化WebView
- C# Winform程式介面優化例項C#ORM優化
- 微信小程式效能優化微信小程式優化
- 小程式效能優化總結優化
- 【微信小程式】效能優化微信小程式優化
- 淺談小程式效能優化優化
- Web 頁面優化專項 > Lighthouse > 效能分數優化Web優化
- C# 程式碼效能優化舉例C#優化
- 正則式 REGEX - 例項
- spark效能優化(一)Spark優化
- Mysql效能優化一MySql優化
- Oracle效能優化-SQL優化(案例一)Oracle優化SQL
- 幾個 JavaScript 效能優化小 TipJavaScript優化
- 微信小程式效能優化方案微信小程式優化
- outline優化一例優化
- 效能優化小冊 - 提高網頁響應速度:優化你的 CDN 效能優化網頁
- iptables 常用規則使用例項
- 讀小程式效能優優化實踐-筆記優化筆記
- 如何使用 MySQL 慢查詢日誌進行效能優化 - Profiling、mysqldumpslow 例項詳解MySql優化
- Kafka效能測試例項Kafka
- php例項化物件的例項方法PHP物件
- 【前端效能優化】vue效能優化前端優化Vue
- 實戰 PerfDog 優化小遊戲效能優化遊戲
- (iOS) UICollectionViewLayoutInvalidationContext效能優化 詳細流程圖 + 範例iOSUIViewContext優化流程圖
- 例項化list
- Android效能優化筆記(一)——啟動優化Android優化筆記
- 【譯】21 項優化 React App 效能的技術優化ReactAPP