每個資料庫平台上的sql開發人員都是在困難中求得生存,我們總是一次又一次犯同樣的錯誤,這是因為資料庫領域還相對不成熟,是的,每個資料庫廠商都在做著各種不同的努力,但作為開發人員仍然要克服各種問題,無論是在sql server,oracle,db2,sybase,mysql資料庫,還是其它關聯式資料庫平台上編寫sql**,併發性、資源管理、空間管理和sql執行速度總是困擾著開發人員。
遺憾的是,其中部分問題的解決沒有靈丹妙藥,也幾乎沒有最佳實踐。通常,開發人員有自己喜歡的sql書寫習慣,一般不願意去研究其它可行方案,當然這可能是因為缺少培訓的原因。我見得最多的就是在測試環境中sql查詢執行良好,但尚未在生產系統上進行試執行,就草草收場了,至於後來發現有問題,再被動式修改,因此終端使用者就痛苦了。
我不期望開發人員成為dba,但我們編寫**時必須考慮生產時的問題,如果不在開發初期這麼做,dba發現後只能迫使我們返工。
我們通常說資料庫除錯是一門技術,更是一門藝術,這是因為很少有現成的規則可以適應一切問題的解決,你在乙個系統上解決的問題在另乙個系統上可能就不是問題了,反之亦然。涉及到查詢調整時,沒有乙個答案是完全正確的,但這並不意味著你應該放棄。
1、用case代替update
要更新一條記錄,我們立即會想到update,這個問題非常常見,許多開發人員經常忽視這個原則,因為使用update看起來非常自然,非常合乎邏輯。
假設你從customer表中提取記錄,你想將超過10萬美元的訂單標記為「preferred」,因此你會想到使用一條update語句將customerrank列更新為「preferred」,問題是update語句是有日誌的,這就意味著每條記錄它會寫兩次,解決這個問題的辦法就是在sql查詢中內嵌case語句,在向表寫入「preferred」標誌前,它會用訂單金額條件對每一行進行檢查,滿足條件的才會更新,效能的提公升是驚人的。
2、不要盲目地重用**
這個問題也非常常見,在工作中直接用別人寫好的**是一件痛快的事情,你知道這些**可以查詢出你需要的資料,但問題是往往有些資料不是你需要的,但我們常常不願意做一下修改,因此返回的資料集往往是乙個超集,很可能多用乙個外連線或是乙個where子句就可以解決問題,因此在復用**時最好檢查一下,如有必要略做適應性修改。
3、只提取你需要的列
這個問題和2有點類似,但這次是指定具體的列。也許我們在使用select * 時感覺很暢快,多省事呀!如果要將每個列名都寫出來,太麻煩了,這是很多人的想法,但這種想法是錯誤的,因為這樣做會取出多餘的資料列,我無數次看到犯這種錯誤的**,曾經有一位開發人員對一張有120列,上百萬行資料的表使用select * 查詢,但他只會用到其中的三五列,這是對資源的極大浪費,我們建議拒絕書寫select * ,你要什麼就查詢什麼,多餘的返回結果對你沒用,雖然不影響你要實現的功能,但對資料庫效能卻有極大的影響。
4、盡可能只查詢一次大表
這也是我看到很多人犯的錯誤,例如,某儲存過程從一張上百萬條記錄的大表中取資料,開發人員想提取居住在加利福利亞且收入高於4萬美元的客戶資訊,因此它先將居住在加利福利亞的客戶取出放在一張臨時表中,然後再查詢收入高於4萬美元的客戶,將查詢結果放入另一張臨時表中,最後,他連線這兩張臨時表查詢出最終的結果。
可能有人認為我是在開玩笑吧?但事實是確實有人這麼做,這應該在乙個查詢中就能完成,卻查詢了兩次大表。
有種稍微不同的情況是,當乙個過程中的多個步驟需要大表的子集時,每一步可能都必須查詢一次大表。避免多次查詢的辦法是持久化第一次查詢的子集,然後將後面的步驟指向該持久化子集。
5、使用臨時表
這個問題解決起來可能稍微有點麻煩,但其效果比較明顯,其實在很多時候你都可以使用臨時表,通過臨時表可以有效地減少對大表的操作,如果你必須連線乙個表到大表,並且在大表上有條件,這時就可以將大表中需要的資料輸出到臨時表中,然後再用該臨時表進行連線,這樣查詢速度會有明顯改進。如果你的儲存過程中有多個查詢需要需要連線到相同的表時,也可以使用臨時表。
6、預存資料
並不是所有時候你都有機會利用該技術,但一旦能利用上,你會發現它是節省伺服器資源很有效的辦法。
但遺憾的是,很多開發人員都在盡力迴避這種技術,實際上只需要建立乙個檢視就可以把問題解決了,但這種方法的問題是每個需要它的報表執行時都會執行一次,但對於同乙個報表,假設10分鐘前執行了一次,現在有人要再執行該報表,那麼對大表的連線操作就可以避免掉了。我建議對那些經常被查詢的表使用該技術將資料預存起來,可以節省大量的伺服器資源。
7、分批刪除和更新
這也是乙個容易被忽視的技巧,對乙個大表做資料刪除或更新操作,如果操作不當可能是一場噩夢,問題是這兩種操作都是單一的事務,如果你需要殺死它們,或它們在執行時系統遇到問題,必須全部回滾整個事務,這個時間可能非常長,這就是為什麼我們在刪除數十萬條記錄時,如果試圖中途殺死程序幾乎沒用的原因,這些操作也會影響到其它事務,搞不好會造成死迴圈,因此應慎用。
解決這個問題的辦法就是分批少量刪除或更新,首先,無論什麼原因需要結束事務,只需要回滾少量的行,此外,小批量提交資料寫入磁碟,對i/o的要求也更低,併發性可以大大提高。
另外要提醒的是,執行刪除和更新操作應盡量選擇非高峰時段。
總結遵循這些方法總是能收到效果,但在實踐中,應該評估選用一種或幾種最佳方案,大家一定要記住,沒有那種辦法是萬能的。另外,這些技巧適用於所有資料庫品種,因此你必須全部掌握!
提高SQL查詢效能
適當遵循一些原則可以讓工作變得更加輕鬆,它們可以幫助提高sql查詢速度 1 用case代替update 要更新一條記錄,我們立即會想到update,這個問題非常常見,許多開發人員經常忽視這個原則,因為使用update看起來非常自然,非常合乎邏輯。假設你從customer表中提取記錄,你想將超過10萬...
提高 SQL 效能的方法
某些時候,查詢需要將資料與其他一些可能只能通過執行 group by 然後執行標準查詢才能收集的資料進行聯接。例如,如果要查詢最新五個定單的有關資訊,您首先需要知道是哪些定單。這可以使用返回定單 id 的 sql 查詢來檢索。此資料就會儲存在臨時表 這是乙個常用技術 中,然後與 products 表...
提高SQL效能的方法
一 問題的提出 在應用系統開發初期,由於開發資料庫資料比較少,對於查詢sql語句,複雜檢視的的編寫等體會不出sql語句各種寫法的效能優劣,但是如果將應用系統提交實際應用後,隨著資料庫中資料的增加,系統的響應速度就成為目前系統需要解決的最主要的問題之一。系統優化中乙個很重要的方面就是sql語句的優化。...