優化儲存過程有很多種方法,下面介紹最常用的7種。
1.使用set nocount on選項
我們使用select語句時,除了返回對應的結果集外,還會返回相應的影響行數。使用set nocount on後,除了資料集就不會返回額外的資訊了,減小網路流量。
2.使用確定的schema
在使用表,儲存過程,函式等等時,最好加上確定的schema。這樣可以使sql server直接找到對應目標,避免去計畫快取中搜尋。而且搜尋會導致編譯鎖定,最終影響效能。比如select * from dbo.testtable比select * from testtable要好。from testtable會在當前schema下搜尋,如果沒有,再去dbo下面搜尋,影響效能。而且如果你的表是csdn.testtable的話,那麼select * from testtable會直接報找不到表的錯誤。所以寫上具體的schema也是乙個好習慣。
3.自定義儲存過程不要以sp_開頭
因為以sp_開頭的儲存過程預設為系統儲存過程,所以首先會去master庫中找,然後在當前資料庫找。建議使用usp_或者其他標識開頭。
4.使用sp_executesql替代exec
原因在inside microsoft sql server 2005 t-sql programming書中的第四章dynamic sql裡面有具體描述。這裡只是簡單說明一下:sp_executesql可以使用引數化,從而可以重用執行計畫。exec就是純拼sql語句。
5.少使用游標
可以參考inside microsoft sql server 2005 t-sql programming書中的第三章cursors裡面有具體描述。總體來說,sql是個集合語言,對於集合運算具有較高的效能,而cursors是過程運算。比如對乙個100萬行的資料進行查詢,游標需要讀表100萬次,而不使用游標只需要少量幾次讀取。
6.事務越短越好
sql server支援併發操作。如果事務過多過長,或是隔離級別過高,都會造成併發操作的阻塞,死鎖。此時現象是查詢極慢,同時cup佔用率極低。
7.使用try-catch來處理錯誤異常
sql server 2005及以上版本提供對try-catch的支援,語法為:
begin try
----your code
end try
begin catch
--error dispose
end catch
一般情況可以將try-catch同事務結合在一起使用。
begin try
begin tran
--select
--update
--delete
--…………
commit
end try
begin catch
--if error
rollback
end catch
********************== 分割線 ********************===
『自己的一些調優經驗』
1. 少使用游標是個很好的建議,為此,我自己也遇到過一些事故,是游標所造成的,由於,游標是逐行逐行操作的,當記錄較多時,經常會遇到超時的情況。
2. 多表join做查詢時,查詢的字段盡量不要使用case when then else end的語法,或者使用使用者函式,例如:
select (case when ftype=1 then '是' else '否' end) as ftypename, dbo.f_getfullname(fid) as ffullname from table1 inner join table2……
當兩個表的資料量非常大時,你可以在查詢分析器中明顯感覺到:直接查詢ftype和fid與查詢上面兩個欄位的速度,很可能使用了乙個case when then就導致超時。
針對這種情況,可以分兩種做法:
第一,把一些簡單的轉換可以放在程式中完成。
第二,如果需要通過id查詢全名或者全稱,類似的,可以建立好檢視,直接查檢視,或者,先把所有的ffullname查出來放到臨時表中,直接join臨時表(如果這個資料不是很多的話),獲得ffullname。
3. 少使用一些巢狀的查詢,用臨時表快取中間資料,例如:
select * from table1
inner join (
select count(1) as count, table2.id2 from table2 inner join table3 on id2=id3 group by table2.id2
) as t1 on t1.id1 = table1.id1
我曾經遇到這樣情況,上面的語句是那種情況的簡化版本,把其他不影響結果的**都去掉了,發現乙個奇怪的現象:巢狀查詢的結果集並不大,大約就200多行,table1有6w條記錄,結果,這個查詢語句超時,查詢分析器中執行2分鐘也得不到結果。
後來,這樣一改,就ok了,3秒出結果:
select count(1) as count, table2.id2 into #temp from table2 inner join table3 on id2=id3 group by table2.id2
select * from table1
inner join #temp as t1 on t1.id1 = table1.id1
這樣一改,效率提公升了幾十倍,猜想:可能是巢狀的查詢是動態的,每一行的join可能都需要先執行巢狀的查詢,從而導致效率極差。
所以,如果查詢足夠複雜,join多個表,需要連線多個通過group by求和、求平均數等運算計算出來的中間資料,那麼,不妨多使用臨時表快取中間資料。
4. 還有一些是必須遵守的一些預設規則,比如:
先過濾後連線。
查詢的字段最要不要用「*」,指定需要用的字段,減少網路流量。
『總結』
對於效能的追求是沒有極限的,做到你所能做到的,這是乙個很好的習慣。
有些業務邏輯放在儲存過程中處理比較方便,而有些業務邏輯交給程式來處理,同樣會提公升系統整體的效率,看實際情況而定。
總之,盡可能減少這些容易引發效能問題的隱患,系統就會跑得更穩定更有效率,一切從小細節做起。
百度 mysql的sql優化 SQL優化問題
該樓層疑似違規已被系統摺疊 隱藏此樓檢視此樓 select cust.code,org.name4 district,org.name3 center,org.name2 org,org.name1,cont.contract code contract num,req.biz type,req.l...
SQL優化 發現問題
1 mysql客戶端連線成功後,通過show status命令可獲取伺服器狀態資訊。通過判斷com insert和com select以及更新和刪除來判斷當前資料庫的應用是以插入更新為主還是以查詢操作為主,以及更重型別的sql大致的執行比例是多少。注意,對於更新操作的計算,是對執行次數的技術,不論提...
MySQL優化 3 慢SQL分析
對慢sql優化一般可以按下面幾步的思路 1 開啟慢查詢日誌,設定超過幾秒為慢sql,抓取慢sql 2 通過explain對慢sql分析 重點 3 show profile查詢sql在mysql伺服器裡的執行細節和生命週期情況 重點 4 對資料庫伺服器的引數調優 1 設定慢查詢 1 設定開啟 set ...