MySQL優化原則

數據庫已成爲互聯網應用必不可少的底層依賴,其中MySQL做爲開源數據庫獲得了更加普遍的應用。最近一直專一於項目工程的開發,對開發過程當中使用到的一些關於數據庫的優化原則進行了總結,但願可以幫助更多的應用開發人員更好的使用MySQL數據庫。數據庫

       MySQL的優化主要包括三個方面,首先是SQL語句的優化,其次是表結構的優化,這裏主要指索引的優化,最後是服務器配置的優化。 緩存

     1.  SQL語句的優化服務器

1) 查詢語句應該儘可能避免全表掃描,首先應該考慮在Where子句以及OrderBy子句上創建索引,可是每一條SQL語句最多隻會走一條索引,而創建過多的索引會帶來插入和更新時的開銷,同時對於區分度不大的字段,應該儘可能避免創建索引,能夠在查詢語句前使用explain關鍵字,查看SQL語句的執行計劃,判斷該查詢語句是否使用了索引;併發

2)應儘可能使用EXISTNOT EXIST代替 INNOT IN,由於後者頗有可能致使全表掃描放棄使用索引;函數

3)應儘可能避免在Where子句中對字段進行NULL判斷,由於NULL判斷會致使全表掃描;性能

4)應儘可能避免在Where子句中使用or做爲鏈接條件,由於一樣會致使全表掃描;優化

5)應儘可能避免在Where子句中使用!=或者<>操做符,一樣會致使全表掃描;spa

6)使用like 「%abc%」 或者like 「%abc」 一樣也會致使全表掃描,而like 「abc%」會使用索引。日誌

7)在使用Union操做符時,應該考慮是否可使用Union ALL來代替,由於Union操做符在進行結果合併時,會對產生的結果進行排序運算,刪除重複記錄,對於沒有該需求的應用應使用Union ALL,後者僅僅只是將結果合併返回,能大幅度提升性能;orm

8)應儘可能避免在Where子句中使用表達式操做符,由於會致使全表掃描;

9)應儘可能避免在Where子句中對字段使用函數,由於一樣會致使全表掃描

10Select語句中儘可能 避免使用「*」,由於在SQL語句在解析的過程當中,會將「*」轉換成全部列的列名,而這個工做是經過查詢數據字典完成的,有必定的開銷;

11)Where子句中,錶鏈接條件應該寫在其餘條件以前,由於Where子句的解析是從後向前的,因此儘可能把可以過濾到多數記錄的限制條件放在Where子句的末尾;

12)若數據庫表上存在諸如index(a,b,c)之類的聯合索引,則Where子句中條件字段的出現順序應該與索引字段的出現順序一致,不然將沒法使用該聯合索引;

13)From子句中表的出現順序一樣會對SQL語句的執行性能形成影響,From子句在解析時是從後向前的,即寫在末尾的表將被優先處理,應該選擇記錄較少的表做爲基表放在後面,同時若是出現3個及3個以上的錶鏈接查詢時,應該將交叉表做爲基表;

14)儘可能使用>=操做符代替>操做符,例如,以下SQL語句,select dbInstanceIdentifier  from DBInstance where id > 3,該語句應該替換成 select dbInstanceIdentifier from DBInstance where id >=4 ,兩個語句的執行結果是同樣的,可是性能卻不一樣,後者更加 高效,由於前者在執行時,首先會去找等於3的記錄,而後向前掃描,然後者直接定位到等於4的記錄。

2.  表結構的優化

    這裏主要指如何正確的創建索引,由於不合理的索引會致使查詢全表掃描,同時過多的索引會帶來插入和更新的性能開銷;

1)首先要明確每一條SQL語句最多隻可能使用一個索引,若是出現多個可使用的索引,系統會根據執行代價,選擇一個索引執行;

2)對於Innodb表,雖然若是用戶不指定主鍵,系統會自動生成一個主鍵列,可是自動產生的主鍵列有多個問題1. 性能不足,沒法使用cache讀取;2. 併發不足,系統全部無主鍵表,共用一個全局的Auto_Increment列。所以,InnoDB的全部表,在建表同時必須指定主鍵。

3)對於區分度不大的字段,不要創建索引;

4)一個字段只需建一種索引便可,無需創建了惟一索引,又創建INDEX索引。

5)對於大的文本字段或者BLOB字段,不要創建索引;

6)鏈接查詢的鏈接字段應該創建索引;

7)排序字段通常要創建索引;

8)分組統計字段通常要創建索引;

9)正確使用聯合索引,聯合索引的第一個字段是能夠被單獨使用的,例若有以下聯合索引index(userID,dbInstanceID),一下查詢語句是可使用該索引的,select dbInstanceIdentifier from DBInstance where userID=? ,可是語句select dbInstanceIdentifier from DBInstance where dbInstanceID=?就不可使用該索引;

10)索引通常用於記錄比較多的表,假若有表DBInstance,全部查詢都有userID條件字段,目前已知該字段已經可以很好的區分記錄,即每個userID下記錄數量很少,因此該表只需在userID上創建一個索引便可,即便有使用其餘條件字段,因爲每個userID對應的記錄數據很少,因此其餘字段使用不用索引基本無影響,同時也能夠避免創建過多的索引帶來的插入和更新的性能開銷;

       3  MySQL服務器配置優化

            MySQL服務器配置優化主要是指MySQL參數的優化;

           1)MySQL服務器有慢鏈接日誌,能夠將超過必定時間間隔和不使用索引的查詢語句記錄下來方便開發人員跟蹤,能夠經過設置slow_query_log=ON/OFF打開和關閉慢鏈接日誌功能,slow_query_log_file設置慢鏈接日誌的文件名,long_query_time設置超時時間,單位是ms,注意慢鏈接日誌MySQL默認是關閉的;

           2)MySQL有查詢緩存的功能,服務器會保存查詢語句和相應的返回結果來減小相同的查詢形成的服務器開銷,能夠經過設置query_cache_size設置查詢緩存的大小,0表示關閉查詢緩存,可是值得注意的是,一旦該表有更新,則全部的查詢緩存都會失效,默認狀況下,MySQL是關閉查詢緩存的;

           3)能夠經過配置max_connections設置數據庫的最大鏈接數,wait_timeout設置鏈接最長保留時間,該時間單位是s, MySQL默認是8個小時,一旦超過8個小時,數據庫會自動斷開該鏈接,這點在使用數據庫鏈接池時由爲須要注意,由於鏈接池中的鏈接可能已經被服務器斷開了,到那時鏈接池不知道,應用在從鏈接池中獲取到該鏈接使用時就會出錯,max_connect_errors配置若是應用出現屢次異常,則會終止主機鏈接數據庫;

相關文章
相關標籤/搜索