SQL 使用總結六(改善資料庫效能)
1、SQL語句調整是優化生產SQL語句的過程,從而以最有效和最高效的方式獲取結果。首先是查詢裡元素的基本安排,因為簡單的格式化過程就能夠在語句優化中發揮很大作用。
2、資料庫調整和SQL語句調整的區別
- 資料庫調整是調整實際資料庫的過程,其目的是確保資料庫的設計能夠最好的滿足使用者對資料庫操作的需求;
- SQL語句調整的目的是利用資料庫和系統資源、索引,針對資料庫的當前狀態進行最有效的訪問,從而減少對資料庫執行查詢所需的開銷。
3、提高SQL語句可讀性
讓語句具有良好可讀性的基本原則如下:
-
- 每個子句都已新行開頭。如select和from不在同一行。
- 當子句裡的引數超過一行長度需要換行時,利用製表符(TAB)或者空格形成縮排。
- 以一致的方式使用製表符和空格。
- 當語句使用多個表時,使用表的別名。
- 如果SQL實現裡允許使用註釋,應該在語句裡有節制的使用。
- 如果在select語句裡有多個欄位,就讓每個欄位從新行開始。
- 如果from語句裡有多個表,就讓每個表從新行開始。
- 讓where子句裡每個條件都已新行開始。
注:雖然提高語句的可讀性並不會直接改善其效能,但這樣會幫助我們更方便的修改和調整很長和很複雜的語句。
4、from子句裡表的順序
通常把較小的表列在前面,把較大的表放在後面,這樣會得到更好的效能(按ANSI標準)。但是具體使用需要檢視具體資料庫的優化器文件,因為每個具體資料庫的優化器對錶的執行順序可能不同。
5、結合條件的次序
在where子句裡,來自基表的欄位一般放在結合操作的右側,要被結合的表通常按從小到大的順序排序。
6、最嚴格條件
最嚴格條件通常是SQL查詢達到最優效能的關鍵因素。它就是where子句裡返回最少記錄的條件。我們應該讓SQL優化器優先計算最嚴格條件,從而減少查詢的開銷。最嚴格條件的位置取決於具體資料庫優化器的工作方式。
從實踐總結的經驗來看,最好使用具有索引的欄位作為查詢裡的最嚴格條件。
7、全表掃描:對於小型表,全表掃描可能會比使用索引具有更好的效能。
8、索引通常會改善查詢的效能。
下面列舉應該被索引的資料
- 作為主鍵的欄位;
- 作為外來鍵的欄位;
- 在結合表裡經常使用的欄位;
- 經常在查詢裡作為條件的欄位;
- 大部分值是唯一的欄位。
9、使用LIKE操作符和萬用字元
LIKE操作符是個很有用的工具,它能夠以靈活的方式為查詢設定條件。
假設我們要編寫一個查詢,從表EMPLYEE_TBL裡選擇欄位EMP_ID,LAST_NAME,FIRST_NAME和STATE,獲得姓為Stevens的僱員ID,姓名和所在的州。下面3個例子使用了不同的萬用字元。
第一個查詢:
SELECT EMP_ID,LAST_NAME,FIRST_NAME,STATE
FROM EMPLOYEE_TBL
WHRER LAST_NAME LIKE 'STEVENS'
第二個查詢:
SELECT EMP_ID,LAST_NAME,FIRST_NAME,STATE
FROM EMPLOYEE_TBL
WHRER LAST_NAME LIKE '%EVENS%'
第三個查詢:
SELECT EMP_ID,LAST_NAME,FIRST_NAME,STATE
FROM EMPLOYEE_TBL
WHRER LAST_NAME LIKE 'ST%'
這些SQL語句並不是必須返回同樣的結果。更可能的情況是,查詢1利用了索引的優勢,返回的記錄比其他兩個查詢少。查詢2和查詢3沒有明確指定要返回的資料,其檢索速度要比查詢1慢。另外,查詢3應該比查詢2更快,因為它指定了搜尋字串的開頭,因此它能夠利用索引。
10、避免使用OR操作符:在SQL語句裡用謂詞IN替代OR操作符能夠提高資料庫檢索速度。
11、避免使用HAVING子句
HAVING子句很有用,可以減少GROUP BY子句返回的資料,但使用它也是要付出代價的。HAVING子句會讓SQL優化器進行額外的工作,也就需要額外的時間。
12、避免大規模的排序操作
資料庫是經常需要排序的,排序最主要的問題是會影響SQL語句的響應時間。由於大規模排序操作不是總可以避免的,所以最好把大規模排序在批處理過程裡,在資料庫使用的非繁忙時間執行,從而避免影響大多數使用者程序的效能。
13、使用儲存過程
儲存過程是經過編譯的、以可執行格式永久儲存在資料庫裡的SQL語句。尤其是對經常使用的SQL語句,生成儲存過程是非常有必要的。
14、批量載入時關閉索引:批量載入時,索引可能會嚴重的降低效能。在批載入操作的前後刪除並重建索引可以還可以減少索引裡的碎片。
15、基於成本的優化
使用者可能經常會遇到需要進行SQL語句調整的資料庫。這類系統在任何一個時間點上往往都有數千條SQL語句正在執行。要優化進行調整所花費的時間,需要首先確定需要調整的查詢型別。這就是我們所關注的,基於成本的優化試圖確定什麼樣的查詢造成了系統資源的額外消耗。例如,如果我們用執行時間來作為衡量標準的話,如下兩個查詢會獲得相應的執行時間:
SELECT * FROM CUSTOMER_TBL
WHERE CUST_NAME LIKE '%LE%' 2sec
SELECT * FROM EMPLOYEE_TBL
WHERE LAST_NAME LIKE 'G%' 1sec
簡單來看,第一個語句似乎就是我們需要進行優化的查詢。但是,如果第二個語句每小時執行1000次,而第一個語句每小時執行10次,情況又怎麼樣呢?結果完全相反。
基於成本的優化根據資源消耗量對SQL語句進行排序。根據查詢的衡量方法(如執行時間,讀庫次數等)以及給定時間段內的執行次數,可以方便的確定資源消耗量:
總計資源消耗 = 衡量方法 X 執行次數
使用這種方法,可以最大程度的獲得調整收益。在上面的例子中,如果我們能夠將每條語句的執行時間減半,就可以很方便的看出所節省的時間:
statement #1 : 1sec * 10 executions = 10 sec of computational savings
statement #2 : 0.5sec * 1000 executions = 500 sec of computational savings
這樣就很容易理解,為什麼要把寶貴的時間花在第二條語句上了。這不僅僅優化了資料庫,也同時優化了使用者的時間。
16、效能工具
很多關係型資料庫具有內建的工具用於SQL語句和資料庫效能調整。如,Oracle有一個名為EXPLAIN PLAN的工具,可以向用戶顯示SQL語句的執行計劃。還有一個工具是TKPROF,它可以測量SQL語句的實際執行時間。在SQL Server中有一個Query Analyzer,可以向用戶提高估計的執行計劃或者已經執行查詢的統計引數。
PS:1、以上內容基於ANSI標準,不針對具體資料庫平臺;
2、以上都是以理論進行討論,實際的工作中,需要考慮很多因素,設計人員的經驗等,花費一定的時間,綜合考慮的情況下,甚至需要不斷的嘗試才可能找到適合需要的優化方案。
3、現在的實際開發中,其實對資料庫的設計不是那麼嚴格(比如完整性約束等都是缺失的),建議更多的開發人員花點時間完善資料庫設計的優化,以改善資料庫效能。(現在資料越來越加的重要)