MySQL—淺談優化

索引

通過使用索引,可以大大提高SQL的性能。
數據庫中索引有如下幾類:

  • B+樹索引 :MyISAM和InnoDB引擎默認使用的索引,最傳統的索引。底層使用了B+樹結構,查詢效率和樹高度成正比,樹的高度在數據庫中就代表了I/O次數。B+樹索引又可以分爲聚集和非聚集索引。

    • 聚集索引:聚集索引的數據頁存放的是完整的記錄,B+樹的葉子存放的是數據。
    • 非聚集索引:B+樹的葉子存放的是記錄的主鍵,所以使用非聚集索引只能查詢還需要使用聚集索引插敘數據。
  • 哈希索引 :和數據量大小沒有關係,查詢複雜度爲O(1),因此是比B+樹索引更加有效的查詢方式。只有Memory/HEAP引擎支持,InnoDB支持自適應的哈希索引。自適應的哈希索引由引擎自己完成的,用戶不能創建。哈希索引索引不是對全表數據進行索引,而是系統認爲的熱點頁的數據創建索引。自適應的哈希索引是在內存中創建的,所以不能持久化。

  • 全文索引:用於實現關鍵字的查詢,是MyISAM的特殊索引,可以在字符串列上使用全文索引,但是InnoDB不支持這種索引。

  • RTree索引:空間索引,是MyISAM的特殊索引,主要用於地理空間數據類型,使用比較少。

PS:MyISAM的索引是屬於非聚集索引的,因爲存儲結構決定了數據和索引分開。InnoDB的主鍵索引是聚集索引,非主鍵索引就是非聚集索引。

索引使用的場合

 1. 使用匹配全值,對所有列都指定具體值,也就是對索引中的所有列都有等值匹配的條件。例如:select * from xxx where colums1=value1 and colums2=value2.
 2. 匹配值的範圍查詢,對索引值能夠範圍查找。例如:select * from xxx where colums1>=value1 and colums2<value2 。
 3. 匹配最左前綴。僅僅使用索引中的最左列查找,比如col1+col2+col3能被col1,clo1+col2,col1+col2+col3的查詢使用到,也稱最左匹配原則。
 4. 僅僅對索引進行查詢,也就是查詢的列都在索引字段裏面。
 5. 匹配列前綴,僅僅使用索引中的第一項,並且只包含索引第一列的開頭一部分進行查找。
 6. 實現索引部分精確匹配,其他部分範圍匹配。例如:select * from xxx where index_col=value and other_cols>=xxx。
 7. 如果列名的索引,那麼使用列名=null就會用到索引。

存在索引但是不能使用索引的場合

  1. 以%開頭的LIKE查詢不能使用索引。
  2. 數據類型隱式轉換時,特別是使用字符串類型時,在where後面一定要加上單引號
  3. 複合索引情況下,不滿足最左原則是不使用複合索引的。
  4. 如果使用索引比搜索全表來的慢,不會使用索引。
  5. 使用or分割開的條件,如果or前面有索引,後面沒索引則不會使用索引。

常用SQL優化

大批量插入

對於大批量插入,MyISAM關閉唯一索引的更新。插入數據以後再打開索引更新,也就是先插入數據然後再對數據檢查。
對於InnoDB:
1.應該將插入的數據按照主鍵順尋排列好
2.導入數據之前關閉數據校驗,導入數據結束以後再開啓
3.導入數據前關閉自動提交,導入數據以後再開啓自動提交

對於一般的INSERT語句,應該使用多個值表的語句。例如:insert into table value (xxx),(xxx),(xxx)。。。。。。

ORDER BY的優化

MySQL中有兩種排序方法,第一種直接通過有序的索引順序返回有序的數據,這種方式無需額外的排序,效率高。第二種是Filesort,就是對返回的結果進行一次排序,所有不是通過索引直接返回結果的都是Filesort。因此,我們的優化目標就是減少Filesort,而通過索引直接返回有序結果。所以,在SQL語句中,WHERE條件和ORDERBY要使用相同的索引,並且ORDERBY的順序和索引相同,並且ORDERBY的順序都是降序或者升序,否則肯定需要使用Filesort。

GROUP BY的優化

默認情況下,MySQL會對於GROUP BY中的字段進行排序,如果我們需要這種排序,那麼對MySQL的實際執行沒有影響。但是如果我們並不需要對結果進行排序,那麼我們可以指定ORDER BY NULL禁止GROUP BY帶來的排序

嵌套語句優化

SQL的子查詢可以使用SELECT創建單列的查詢結果,然後把這個結果作爲過濾條件用在另外一個查詢中,雖然子查詢好處多多,但是有時候使用連接JOIN會有更好的效率,那是因爲使用JOIN不需要在內存中創建臨時表來完成查詢工作;而子查詢會在內存中建立一個臨時表,這回降低查詢效率。

OR優化

對於含有OR的查詢語句,只要存在一個沒有索引的列,那麼就會進行全表查詢而放棄使用索引。因此,如果要使用索引,則OR之間的每一個條件列都要用到索引,沒有索引就串講索引。

分頁查詢的優化

使用分頁查詢語句時,例如”limit 10000,20”,此時數據庫會查詢前面10020條記錄,而我們只需要後20條記錄,那麼前10000條記錄的查詢是無用,這就會造成不必要的性能浪費。
優化思路一:先在索引上完成排序分頁的操作,然會根據主鍵關聯回原表查詢需要的其他內容。
優化思路二:把LIMIT查詢轉化爲某一個位置的查詢。

應用優化

除了對數據庫本身優化以外,我們還可以對使用數據的外部應用進行優化。

  • 使用數據庫連接池:數據庫連接池和線程池類似,目的是減少重複連接-斷開操作的開銷,常見的數據庫連接池有:C3P0,DBCP還有阿里的druid。
  • 使用查詢緩存:第一次查詢數據庫時,將數據內容進行緩存,下一次做同樣的查詢就直接從緩存中取數據即可,不需要再次訪問數據庫。常見的數據庫緩存系統有:Redis,Memcached。
  • 負載均衡:利用均衡算法,將固定的負載量分佈到不同服務器,以此減輕單臺服務器的負載,達到優化的目的。具體方式如:使用MySQL的主從複製分流查詢操作,或者使用分佈式數據庫架構,其具體實現可以使用MySQL的CLUSTER功能。

總結:主要講了MySQL常見的優化除了使用索引、SQL語句優化、外部引用優化,除此以外MySQL還有許多優化的辦法,如優化MySQL Server,優化磁盤等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章