SQL查詢優化


記點SQL查詢的東西:

1,查詢的模糊匹配:

  盡量避免在一個負債查詢里面使用LIKE-"%xx%","%"會導致相關列的索引無法使用,最好不好用,解決辦法:

  根據輸入條件,先查詢和確定符合條件的結果,並把相關記錄保存在一個臨時表中,然后再用臨時表去做復雜關聯。

2,索引問題

  經常發現有很多后台程序的性能問題是因為缺少何時索引造成的,有的表甚至沒有索引。這種情況往往是因為在設計表時,沒有定義索引,而開發初期,由於表中的數據不多,所以感覺不到索引對性能的影響,但是一旦項目發布,表中數據多了之后,缺少索引對性能的影響便會越來越大。

  還有不要在建立索引的數據列上進行一下操作:

  (1)避免對索引字段進行計算操作;

  (2)避免在索引字段上使用not、<>、!=;

  (3)避免在索引字段單使用 IS NULL、IS NOT NULL;

  (4)避免在索引字段單出現數據類型轉換;

  (5)避免在索引字段上使用函數;

  (6)避免建立索引的列中使用空值。

3,復雜操作

  部分SQL語句寫的很復雜(經常嵌套多級子查詢),這樣也會對性能造成一定的影響,而且不利於以后的維護工作。可以考慮適當拆成幾步來完成,先生成一些臨時數據表,再進行關聯操作。

4,UNION ALL \ UNION

  在可以使用UNION ALL的語句中,使用了UNION。UNION 因為會將各查詢子集的記錄做比較,故比起UNION ALL性能上會差很多。一般來說,如果使用UNION ALL能滿足要求的話,務必使用UNION ALL。

  還有一種情況是,就是雖然要求幾個子集作並集需要過濾掉重復記錄,但是由於腳本的特殊性,不可能存在重復記錄,這是便應該使用UNION ALL。

5,對於WHERE語句的法則:

  (1)盡量避在WHERE子句中使用in、not in或者having,可以使用exist、not exist代替in、not in,因為in相比exist會有比較操作,參考:http://stackoverflow.com/questions/24929/difference-between-exists-and-in-in-sql

  (2)不要以字符格式聲明數字,要以數字格式聲明字符值,日期同樣,否則會使索引無效,產生全表掃面。例如: 

SELECT no,name WHERE no = 1111
而不要使用:
SELECT no,name WHERE no = '1111' 

 

  (3)盡量避免在WHERE子句中對字段進行null值判斷,否則將導致引擎放棄索引而進行全表掃描,如:SELECT name FROM T WHERE no is null;可以在no上設置默認值0,確保表中no列沒有null值,然后這樣查詢SELECT name FROM T WHERE no = 0;

  (4)盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描;

  (5)盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如: 

    select id from t where num=10 or num=20
    可以這樣查詢:
    select id from t where num=10
    union all
    select id from t where num=20

  (6)in 和 not in 也要慎用,否則會導致全表掃描  

6,對於SELECT語句,用具體的字段列表代理*

7,排序

  避免使用消耗資源的操作,例如DISTINCT、UNION、MINUS、INTERSECT、ORDER BY的SQL語句會啟動SQL引擎執行消耗資源的排序功能。

  DISTINCT需要一次排序操作,而其他的至少需要執行兩次排序。

8,臨時表

  慎重使用臨時表可以極大的提高系統性能。

9,其他

  (1)在使用索引字段作為條件時,如果該索引是復合索引,那么必須使用到該索引中的第一個字段作為條件時才能保證系統使用該索引,否則索引是不會被使用的,並且應可能讓字段順序與索引順序相一致。

  (2)並不是所有索引對查詢都有效,SQL是根據表中數據來進行查詢優化的,當索引列有大量數據重復時,SQL查詢可能不會去利用索引, 如一表中有字段sex,male、female幾乎各一半,那么即使在sex上建了索引也對查詢效率起不了作用。

  (3)索引並不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率, 因為 insert 或 update時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。 一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。

  (4)盡量使用數字型字段,若只含數值信息的字段盡量不要設計為字符型,這會降低查詢和連接的性能,並會增加存儲開銷。 這是因為引擎在處理查詢和連接時會逐個比較字符串中每一個字符,而對於數字型而言只需要比較一次就夠了。

  (5)關於nvarchar、varchar、nchar、char的選擇:參考文章:http://www.cnblogs.com/lichang1987/archive/2009/03/04/1403166.html,現在是基本上使用nvarchar因為varchar最終也會轉成nvarchar?

    盡量使用varcha代理char,因為首先變長字段存儲空間小,可以節省存儲空間,其次對於查詢來說,在一個相對較小的字段內搜索效率顯然要高些。

  (6)盡量避免使用游標,因為游標的效率較差,應先尋找基於集的解決方案來解決問題,基於集的方法通常更有效

  (7)盡量避免使用大事務操作,提高系統並發能力

  (8)盡量避免像客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM