1、不要取出全部列,取出全部列,會讓優化器無法完成索引覆寫掃描這類優化,還會為服務器帶來額外的I/O、記憶體和CPU的消耗,應該嚴格禁止SELECT * 的寫法,MySQL使用如下三種方式應用WHERE條件,從好到壞依次為:
1.1 在索引中使用WHERE條件來過濾不匹配的記錄,這是在存盤引擎層完成的,
1.2 使用索引覆寫掃描(Extra列中出現了Using index)來回傳記錄,直接從索引中過濾不需要的記錄并回傳命中的結果,這是在MySQL服務器層完成的,但無須在回表查詢記錄,
1.3 從資料表中回傳資料,然后過濾不滿足條件的記錄(在Extra列中出現Using Where),這在MySQL服務器層完成,MySQL需要先從資料表獨處記錄然后過濾,
上面的例子說明了好的索引很重要,
2、如果發現查詢需要掃描大量的資料但值回傳少數的行,那么可以嘗試下面的技巧優化它:
2.1 使用索引覆寫掃描,把所有需要用的列都放到索引中,這樣存盤引擎無須回表獲取對應行就可以回傳結果了,
2.2 改變庫表結構,例如使用單獨的匯總表,
2.3 重寫這個復雜的查詢,讓MySQL優化器能夠以更優化的方式執行這個查詢,
重構查詢:
1、一個復雜查詢還是多個簡單查詢;
2、切分查詢;
例如:
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
一次洗掉一萬行資料一般來說比較高效,如果每次洗掉資料后,都暫停一會兒再做下一次洗掉,這樣也可以將服務器上原本一次性的壓力分散到一個很長的時間段中,可以大大的減少對服務器的影響
3、分解關聯查詢
查詢優化處理
查詢優化處理包括多個子階段:決議SQL、預處理、優化SQL執行計劃,這個程序中的任何錯誤(例如語法錯誤)都可能終止查詢,
優化策略可以簡單的分為兩種:
1、靜態優化:直接對決議樹進行分析,并完成優化
2、動態優化:動態優化跟查詢背景關系有關,也可能和很多其他因素有關,例如WHERE條件中的取值、索引中條目對應的資料行數等,
MySQL能夠處理的優化型別:
- 重新定義關聯表的順序,
- 將外連接轉化成內連接,
- 使用等價變換規則,
- 優化COUNT()、MIN()和MAX(),
- 預估并轉化為常數運算式
- 覆寫索引掃描
- 子查詢優化
- 提前終止查詢
- 等值傳播
- 串列IN()的比較
怎么查看優化器重寫后的SQL?
用到了explain extended和showwarnings

用ORDER BY排序,如果查詢中有LIMIT的話,LIMT也會在排序之后應用,所以即使需要回傳較少的資料,歷史表和需要排序的資料量仍然會非常大,MySQL5.6在這里做了很多重要的改進,當只需要回傳部分排序結果的時候,例如使用LIMIT子句,MySQL不再對所有的結果進行排序,而是根據實際情況,選擇拋棄不滿足條件的結果,然后再進行排序,
參考:
[1]Baron Schwartz等 著,寧海元等 譯 ;《高性能MySQL》(第3版); 電子工業出版社 ,2013
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/87443.html
標籤:MySQL
上一篇:簡單的圖片排序
下一篇:MySQL資料庫(三)簡介
