mysql-查詢性能優化

一、不要取出所有列,取出所有列,會讓優化器沒法完成索引覆蓋掃描這類優化,還會爲服務器帶來額外的I/O、內存和CPU的消耗。應該嚴格禁止SELECT * 的寫法。MySQL使用以下三種方式應用WHERE條件,從好到壞依次爲:服務器

  1.1 在索引中使用WHERE條件來過濾不匹配的記錄。這是在存儲引擎層完成的。性能

  1.2 使用索引覆蓋掃描(Extra列中出現了Using index)來返回記錄,直接從索引中過濾不須要的記錄並返回命中的結果。這是在MySQL服務器層完成的,但無須在回表查詢記錄。優化

  1.3 從數據表中返回數據,而後過濾不知足條件的記錄(在Extra列中出現Using Where)。這在MySQL服務器層完成,MySQL須要先從數據表獨處記錄而後過濾。spa

上面的例子說明了好的索引很重要。code

二、若是發現查詢須要掃描大量的數據但值返回少數的行,那麼能夠嘗試下面的技巧優化它:blog

  2.1 使用索引覆蓋掃描,把全部須要用的列都放到索引中,這樣存儲引擎無須回表獲取對應行就能夠返回結果了。排序

  2.2 改變庫表結構。例如使用單獨的彙總表。索引

  2.3 重寫這個複雜的查詢,讓MySQL優化器可以以更優化的方式執行這個查詢。內存

重構查詢:class

  一、一個複雜查詢仍是多個簡單查詢;

  二、切分查詢;

  例如:

DELECT FROM message WHERE created < DATE_SUB(NOW(),INTERVAL 3 MONTH);

改爲:

rows_affected=0
do{
    rows_affected=do_query(
        "DELECT FROM message WHERE create created < DATE_SUB(NOW(),INTERVAL 3 MONTH) LIMIT 10000"
    )
} while rows_affected > 0

  一次刪除一萬行數據通常來講比較高效,若是每次刪除數據後,都暫停一下子再作下一次刪除,這樣也能夠將服務器上本來一次性的壓力分散到一個很長的時間段中,能夠大大的減小對服務器的影響

  三、分解關聯查詢

查詢優化處理

  查詢優化處理包括多個子階段:解析SQL、預處理、優化SQL執行計劃。這個過程當中的任何錯誤(例如語法錯誤)均可能終止查詢。

  優化策略能夠簡單的分爲兩種:

  一、靜態優化:直接對解析樹進行分析,並完成優化

  二、動態優化:動態優化跟查詢上下文有關,也可能和不少其餘因素有關,例如WHERE條件中的取值、索引中條目對應的數據行數等。

  MySQL可以處理的優化類型:

  • 從新定義關聯表的順序。
  • 將外鏈接轉化成內鏈接。
  • 使用等價變換規則。
  • 優化COUNT()、MIN()和MAX()。
  • 預估並轉化爲常數表達式
  • 覆蓋索引掃描
  • 子查詢優化
  • 提早終止查詢
  • 等值傳播
  • 列表IN()的比較

  怎麼查看優化器重寫後的SQL?

  用到了explain extended和showwarnings

  用ORDER BY排序,若是查詢中有LIMIT的話,LIMT也會在排序以後應用,因此即便須要返回較少的數據,歷史表和須要排序的數據量仍然會很是大。MySQL5.6在這裏作了不少重要的改進。當只須要返回部分排序結果的時候,例如使用LIMIT子句,MySQL再也不對全部的結果進行排序,而是根據實際狀況,選擇拋棄不知足條件的結果,而後再進行排序。

參考:

[1]Baron Schwartz等 著,寧海元等 譯 ;《高性能MySQL》(第3版); 電子工業出版社 ,2013

相關文章
相關標籤/搜索