MySQL調優系列——MySQL經常使用的優化技巧

SQL優化緣由:html

性能低、執行時間太長、等待時間太長、SQL語句欠佳(鏈接查詢)、索引失效、服務器參數設置不合理(緩衝、線程數)mysql

system>const>eq_ref>ref>range>index>all   ,要對type進行優化的前提:有索引sql

其中:system,const只是理想狀況;實際能達到 ref>range數據庫

system(忽略): 只有一條數據的系統表 ;或 衍生表只有一條數據的主查詢服務器

1.經過show status 命令瞭解各類sql的執行效率

2. 定位執行效率較低的SQL語句

開啓慢查詢記錄(在相應的配置文件中添加慢查詢記錄sql最長時間閾值)函數

三、經過Explain分析低效率的SQL語句的執行狀況

-- 實際SQL,查找用戶名爲Jefabc的員工
select * from emp where name = 'Jefabc';
-- 查看SQL是否使用索引,前面加上explain便可
explain select * from emp where name = 'Jefabc'

 

概要描述:性能

id:選擇標識符,優先級
select_type:表示查詢的類型。
table:輸出結果集的表
partitions:匹配的分區
type:表示表的鏈接類型
possible_keys:表示查詢時,可能使用的索引
key:表示實際使用的索引

key_len:索引字段的長度
ref:列與索引的比較
rows:掃描出的行數(估算的行數)
filtered:按表條件過濾的行百分比
Extra:執行狀況的描述和說明 測試

下面對這些字段出現的可能進行解釋:優化

1、 idspa

SELECT識別符。這是SELECT的查詢序列號

個人理解是SQL執行的順序的標識,SQL從大到小的執行

1. id相同時,執行順序由上至下

2. 若是是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行

3. id若是相同,能夠認爲是一組,從上往下順序執行;在全部組中,id值越大,優先級越高,越先執行

-- 查看在研發部而且名字以Jef開頭的員工,經典查詢
explain select e.no, e.name from emp e left join dept d on e.dept_no = d.no where e.name like 'Jef%' and d.name = '研發部';

2、select_type查詢中每一個select子句的類型

PRIMARY:包含子查詢SQL中的 主查詢 (最外層)
SUBQUERY:包含子查詢SQL中的 子查詢 (非最外層)
simple:簡單查詢(不包含子查詢、union)
derived:衍生查詢(使用到了臨時表)

3、table

顯示這一步所訪問數據庫中表名稱(顯示這一行的數據是關於哪張表的),有時不是真實的表名字,多是簡稱,例如上面的e,d,也多是第幾步執行的結果的簡稱

4、type

對錶訪問方式,表示MySQL在表中找到所需行的方式,又稱「訪問類型」。

經常使用的類型有: ALL、index、range、 ref、eq_ref、const、system、NULL(從左到右,性能從差到好)

all:查詢所有表中的數據

index:查詢所有索引中數據

range:檢索指定範圍的行 ,where後面是一個範圍查詢(between   ,> < >=,     特殊:in有時候會失效 ,從而轉爲 無索引all)

ref:非惟一性索引,對於每一個索引鍵的查詢,返回匹配的全部行(0,多)

eq_ref:惟一性索引:對於每一個索引鍵的查詢,返回匹配惟一行數據(有且只有1個,不能多 、不能0)

const:僅僅能查到一條數據的SQL ,用於Primary key 或unique索引  (類型 與索引類型有關)

system(忽略): 只有一條數據的系統表 ;或 衍生表只有一條數據的主查詢

NULL: MySQL在優化過程當中分解語句,執行時甚至不用訪問表或索引,例如從一個索引列裏選取最小值能夠經過單獨索引查找完成。

5、possible_keys

指出MySQL能使用哪一個索引在表中找到記錄,查詢涉及到的字段上若存在索引,則該索引將被列出,但不必定被查詢使用(該查詢能夠利用的索引,若是沒有任何索引顯示 null)

該列徹底獨立於EXPLAIN輸出所示的表的次序。這意味着在possible_keys中的某些鍵實際上不能按生成的表次序使用。
若是該列是NULL,則沒有相關的索引。在這種狀況下,能夠經過檢查WHERE子句看是否它引用某些列或適合索引的列來提升你的查詢性能。若是是這樣,創造一個適當的索引而且再次用EXPLAIN檢查查詢

6、Key

key列顯示MySQL實際決定使用的鍵(索引),必然包含在possible_keys中

若是沒有選擇索引,鍵是NULL。要想強制MySQL使用或忽視possible_keys列中的索引,在查詢中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

7、key_len

表示索引中使用的字節數,可經過該列計算查詢中使用的索引的長度(key_len顯示的值爲索引字段的最大可能長度,並不是實際使用長度,即key_len是根據表定義計算而得,不是經過表內檢索出的)

不損失精確性的狀況下,長度越短越好 

8、ref

列與索引的比較,表示上述表的鏈接匹配條件,即哪些列或常量被用於查找索引列上的值

9、rows

 估算出結果集行數,表示MySQL根據表統計信息及索引選用狀況,估算的找到所需的記錄所須要讀取的行數

10、Extra

該列包含MySQL解決查詢的詳細信息,有如下幾種狀況:

Using where:不用讀取表中全部信息,僅經過索引就能夠獲取所需數據,這發生在對錶的所有的請求列都是同一個索引的部分的時候,表示mysql服務器將在存儲引擎檢索行後再進行過濾

Using temporary:表示MySQL須要使用臨時表來存儲結果集,常見於排序和分組查詢,常見 group by ; order by

Using filesort:當Query中包含 order by 操做,並且沒法利用索引完成的排序操做稱爲「文件排序」

-- 測試Extra的filesort
explain select * from emp order by name;

Using join buffer:改值強調了在獲取鏈接條件時沒有使用索引,而且須要鏈接緩衝區來存儲中間結果。若是出現了這個值,那應該注意,根據查詢的具體狀況可能須要添加索引來改進能。

Impossible where:這個值強調了where語句會致使沒有符合條件的行(經過收集統計信息不可能存在結果)。

Select tables optimized away:這個值意味着僅經過使用索引,優化器可能僅從聚合函數結果中返回一行

No tables used:Query語句中使用from dual 或不含任何from子句

-- explain select now() from dual;

總結:

• EXPLAIN不會告訴你關於觸發器、存儲過程的信息或用戶自定義函數對查詢的影響狀況
• EXPLAIN不考慮各類Cache
• EXPLAIN不能顯示MySQL在執行查詢時所做的優化工做
• 部分統計信息是估算的,並不是精確值
• EXPALIN只能解釋SELECT操做,其餘操做要重寫爲SELECT後查看執行計劃。

注意:要儘可能避免讓type的結果爲all,extra的結果爲:using filesort

4.適當的位置加上索引【注意如下幾種狀況】

  • 較頻繁的做爲查詢條件字段應該建立索引

    select * from order_copy where id = $id

  • 惟一性太差的字段不適合單首創建索引,即便頻繁做爲查詢條件

   select * from order_copy where sex=’女’

  • 更新很是頻繁的字段不適合建立索引

    select * from order_copy where order_state=’未付款’

  • 不會出如今WHERE子句中字段不應建立索引

本文參考:

https://www.cnblogs.com/tufujie/p/9413852.html

https://www.cnblogs.com/itsharehome

相關文章
相關標籤/搜索