2012年4月25日 星期三

[C#] 程式最佳化心得(持續更新)


[C#] 程式最佳化心得(持續更新)
作者:JB

上次系統從Oracle移轉MS Sql Server,雖然吃盡苦頭,但是也學到了不少東西;
尤其是SQLindex的部分。 去年主管問小弟,有沒有辦法再將跑三個半小時的程式再加速,小弟當時很無奈的說:「對不起! 我已經盡力了。」

時值今日,剛好有機會再度修改這支程式,也讓我有機會自打嘴巴。 深入了解後,才知道可以改善的幅度這麼大。

1.      Algorithm

小弟用Sql Server Profiler觀察AP裡面執行最久的一段Sql,發現需要跑一秒多; 去看一下執行計畫後,才發現沒有吃到index。 一般是馬上去建index,但是我看了一下目前已建立的index,發現只要改這段Sql的邏輯,它就可以吃到目前的index了。

恩,再次執行後,發現這段Sql已經改善到0.6XX秒了,但是AP的整體效能並沒有提昇太多,因為這段SqlAP裡面,反覆執行了一萬多次,這樣算一算總執行時間就要1.5個小時!
於是我去細看這邊的程式邏輯,在不影響邏輯的情況下,多加上這段Sql的執行條件,讓其執行次數減少到幾百次馬上執行時間減少到十幾分鐘!

所以小弟真的覺得要最佳化AP,首先應該是回頭看看演算法有沒有可以調整的地方
J

2.      Database

原以為在在Oracle移轉MS Sql Server的過程,AP只要改改Sql,原有的index建一建就好。 結果兩個資料庫的index運作原理似乎不太..一樣(抱歉,小弟不是DBA,只能這麼粗淺的解釋)
也就是說,原本在Oracle有吃到indexSql,在MS Sql server就不一定了喔。
所以記得要把Sql再拿出來看一下執行計畫!

參考這篇文章:Top 10 steps to optimize data access in SQL Server
以下列出ㄧ些小弟認為很重要的幾項。

(1)       查看執行計畫!

(2)       DistinctGroup by時,避免對欄位進行運算,如Trim(否則完全吃不到index)

(3)       避免對WHERE條件裡面的欄位進行Convert,例如:
where CONVERT(NUMERIC, COL_AMT) = 80

應該寫成
where COL_AMT = ‘000080’
(4)       避免用COUNT來查看表格裡面有沒有資料,而是用Exists (因為Exists只要掃到一筆就回傳True)

(5)       避免把兩個不同型別的欄位,拿來當作JOIN的條件。(恩,常常遇到 ~_~)

(6)       待續

3.      Tools

除了寫好程式,也要好的工具來測試寫好的程式,Visual Studio 2010的效能分析工具實在太佛心來著了。



小弟再慢慢補上心得... 

沒有留言:

張貼留言