資料庫的最佳化和效率

beifengwang發表於2013-10-28
如果要查詢相同的內容,有著不同的多種方法。使用SQL語句查詢資料庫記錄時,儘管使用多種方法可以得到相同的結果,但是如果您使用不同的方法,執行效益上是截然不同的因此,得仔細考慮,如果要查詢相同結果,該使用哪種語句,執行效益比較好。這就是SQL語句的最佳化。以下最佳化語句,針對MSSql資料庫。

1 對查詢進行最佳化,應儘量防止全表掃描,首先應考慮在where及 orderby涉及的列上建立索引。

2 應儘量避免在where子句中對欄位進行 null值判斷,否則將導致引擎放棄使用索引而進行全表掃描。

3 應儘量避免在where子句中使用特殊作符,否則將引擎放棄使用索引而進行全表掃描。

4 應儘量避免在where子句中使用 or來連線條件,否則將導致引擎放棄使用索引而進行全表掃描。

5 in和 notin也要慎用,否則會導致全表掃描。

7 如果在where 子句中使用引數,也會導致全表掃描。因為SQL只有在執行時才會解析區域性變數,但最佳化順序不能將訪問計劃的選擇推遲到執行時;必需在編譯時進行選擇。然而,如果在編譯時建立訪問計劃,變數的值還是未知的因而無法作為索引選擇的輸入項。

8 應儘量避免在where子句中對欄位進行表示式操作,這將導致引擎放棄使用索引而進行全表掃描。

9 應儘量避免在where子句中對欄位進行函式操作,這將導致引擎放棄使用索引而進行全表掃描。

10 不要在where子句進行函式、算術運算或其他表示式運算,否則系統將可能無法正確使用索引。

11 使用索引欄位作為條件時,如果該索引是複合索引,那麼必需使用到該索引中的第一個欄位作為條件時才幹保證系統使用該索引,否則該索引將不會被使用,並且應儘可能的讓欄位順序與索引順序相一致。

12 不要寫一些沒有意義的查詢。

13 很多時候用 exist代替 in一個好的選擇。

14 並不是所有索引對查詢都有效,SQL根據表中資料來進行查詢最佳化的當索引列有大量資料重複時,SQL查詢可能不會去利用索引,如一表中有欄位sexmalefemal幾乎各一半,那麼即使在sex上建了索引也對查詢效率起不了作用。

15 索引並不是越多越好,索引固然可以提高相應的select效率,但同時也降低了insert及 updat效率.

16 應儘可能的防止更新 cluster索引資料列,因為 clustered 索引資料列的順序就是表記錄的物理儲存順序,一旦該列值改變將導致整個表記錄的順序的調整,會耗費相當大的資源。若應用系統需要頻繁更新 clustered 索引資料列,那麼需要考慮是否應將該索引建為 cluster索引。

17 儘量使用數字型欄位,若只含數值資訊的欄位儘量不要設計為字元型,這會降低查詢和連線的效能,並會增加儲存開銷。這是因為引擎在處置查詢和連線時會逐個比較字串中每一個字元,而對於數字型而言只需要比較一次就夠了

18 儘可能的使用長欄位,儲存空間小,可以節省儲存空間,其次對於查詢來說,一個相對較小的欄位內搜尋效率顯然要高些。

19 任何地方用具體的欄位名稱代替

20 儘量使用表變數來代替臨時表。如果表變數包括大量資料,請注意索引非常有限。

21 防止頻繁建立和刪除臨時表,以減少系統表資源的消耗。

22 臨時表並不是不可使用,適當地使用它可以使某些例程更有效,例如,當需要重複引用大型表或常用表中的某個資料集時。但是對於一次性事件,最好使用匯出表。

23 新建臨時表時,如果一次性插入資料量很大,那麼可以使用 selectinto代替 creattabl防止造成大量 log 以提高速度,如果資料量不大,為了緩和系統表的資源,應先creattabl然後insert

24 如果使用到臨時表,儲存過程的最後務必將所有的臨時表顯式刪除,先 truncattabl然後 droptable 這樣可以防止系統表的較長時間鎖定。

25 儘量防止使用遊標,因為遊標的效率較差,如果遊標操作的資料超越1萬行,那麼就應該考慮改寫。

26 使用基於遊標的方法或臨時表方法之前,應先尋找基於集的解決方案來解決問題,基於集的方法通常更有效。

27 與臨時表一樣,遊標並不是不可使用。對小型資料集使用 fast forward 遊標通常要優於其他逐行處理方法,尤其是必需引用幾個表才幹獲得所需的資料時。結果集中包括“合計”例程通常要比使用遊標執行的速度快。如果開發時間允許,基於遊標的方法和基於集的方法都可以嘗試一下,看哪一種方法的效果更好。

28 儘量防止大事務操作,提高系統併發能力。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29212814/viewspace-775189/,如需轉載,請註明出處,否則將追究法律責任。

相關文章