1. 程式人生 > >SQL對程式效能的影響

SQL對程式效能的影響

瞎子和聾子

【先思考一個問題:聾子和瞎子在一起會有什麼結果?】

昨天寫程式,有個小模組是通過分析數十萬條記錄,與異構的資料表進行比對,找出符合條件的資訊。


在第一條查詢中,需要查詢所有記錄的一個欄位,並提取該欄位中的第5至第10個字串,要與異構資料表比較的就是這個字串。在最初的版本中,對於效能並沒有做更多的考慮,先從資料表中獲取所有的記錄組成的資料集,作為目標資料,再從異構資料表中獲取資料集作為比對資料,然後在程式中經過至少兩次遍歷,篩選出想要的結果。在這個版本中,效率很低。比對資料基本上固定,千把條的樣子,目標資料很多,而且會越來越多。但效能的瓶頸並不是出現在程式中多次的遍歷,這些都在記憶體中進行,這點資料量和演算法,對於目前的伺服器來說真的是小菜一碟。經測試,雖然只有幾十萬行的記錄,查詢時間卻需要5秒以上。


我原來的思路是,因為擔心SQL的效能,把從欄位中擷取字串的計算由SQL移至程式中進行,但實踐證明,對於返回大量記錄的SQL,其效率反而更低了。於是,改變思路,還是利用SQL進行篩選,並儘量減少資料量,有了類似下面這一行簡單的查詢:


select distinct substring([prodcode],5,10) pcode from [detail] order by pcode




在這段查詢中,首先是利用substring函式,在sql中就返回了要想的字串,注意這裡substring函式和C#中的區別,它是從1開始索引的,而C#中則是從0開始(我在此走了彎路,如果聰明的你早就知道,請忽略)。然後是前面有個關鍵字distinct,用來消除重複的記錄(這裡存在大量的重複值)。實踐證明,雖然增加了一個擷取字串的計算,但由於返回的記錄大大減少,這種情況下,資料庫伺服器返回結果的時間提升到0秒,也就是說已經是毫秒級了,SSMS(=查詢分析器)給忽略了。


眾所周知,I/O對程式效能的影響相當大,在這個小小的例項中也能看出這一點。最開始,我想當然的以為把計算移到程式中去做,減輕一下資料庫的負擔,同時提高運算效率,卻忽略了這個問題。當SQL返回了大量資料,這些資料要從一個地方移動到另一個地方,從目前的網路效能來看,耽誤的時間絕對是不可以忽略的。


這個故事告訴我們,不能想當然,做程式如此,做任何事情都是如此。

PS :最後不得不又要發個牢騷了,剛才提交的時候,差點又發生前功盡棄的事兒,正文文字框一片空白,和昨天提到的一樣。也許是冥冥之中有神靈在幫我,在點提交按鈕之前的那一瞬間,我打了個冷戰,把這一堆文字複製到了記事本,不然現在可能已經變成了哭泣的百合。我估計的原因是,在文章發表頁面花費的時間太長了。以前也給CSDN提過建議,增加一個自動儲存到草稿箱的功能,但似乎沒有反應。所以,還是自己以後多加個小心吧。