【Mysql】Mysql性能優化

explain執行計劃參數詳解

mysql> explain select * from kt_course order by create_time desc;
+----+-------------+-----------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+-----------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | kt_course | ALL  | NULL          | NULL | NULL    | NULL |   29 | Using filesort |
+----+-------------+-----------+------+---------------+------+---------+------+------+----------------+
1 row in set

select_type

1) SIMPLE:簡單的SELECT,不實用UNION或者子查詢。
2) PRIMARY:最外層SELECT。
3) UNION:第二層,在SELECT之後使用了UNION。
4) DEPENDENT UNION:UNION語句中的第二個SELECT,依賴於外部子查詢。
5) UNION RESULT:UNION的結果。
6) SUBQUERY:子查詢中的第一個SELECT。
7) DEPENDENT SUBQUERY:子查詢中的第一個SELECT,取決於外面的查詢。
8) DERIVED:導出表的SELECT(FROM子句的子查詢)

table

顯示這一行的數據是關於哪張表的

type

type字段比較重要,它標識了查詢是否高效,是使用了全表掃描還是索引掃描

這是重要的列,顯示連接使用了何種類型。
從最好到最差的連接類型:const、eq_reg、ref、range、index和ALL

Type:告訴我們對錶使用的訪問方式,主要包含如下集中類型。

1) all:全表掃描。
2) const:讀常量,最多隻會有一條記錄匹配,由於是常量,實際上只須要讀一次。
3) eq_ref:最多隻會有一條匹配結果,一般是通過主鍵或唯一鍵索引來訪問。
4) fulltext:進行全文索引檢索。
5) index:全索引掃描。
6) index_merge:查詢中同時使用兩個(或更多)索引,然後對索引結果進行合併(merge),再讀取表數據。
7) index_subquery:子查詢中的返回結果字段組合是一個索引(或索引組合),但不是一個主鍵或唯一索引。
8) rang:索引範圍掃描。
9) ref:Join語句中被驅動表索引引用的查詢。
10) ref_or_null:與ref的唯一區別就是在使用索引引用的查詢之外再增加一個空值的查詢。
11) system:系統表,表中只有一行數據;
12) unique_subquery:子查詢中的返回結果字段組合是主鍵或唯一約束。

possible_keys

顯示可能應用在這張表中的索引。如果爲空,沒有可能的索引。可以爲相關的域從WHERE語句中選擇一個合適的語句

key

實際使用的索引。如果爲NULL,則沒有使用索引。很少的情況下,MYSQL會選擇優化不足的索引。這種情況下,可以在SELECT語句中使用USE INDEX(indexname)來強制使用一個索引或者用IGNORE INDEX(indexname)來強制MYSQL忽略索引

key_len

使用的索引的長度。在不損失精確性的情況下,長度越短越好

key_len計算方式 https://www.cnblogs.com/gomysql/p/4004244.html

ref

顯示索引的哪一列被使用了,如果可能的話,是一個常數

rows

mysql查詢優化器根據統計信息,估算sql要查找結果集需要掃描讀取的數據行數,這個值可以直觀的反映出sql的效率,原則上rows數值越小越好

Extra

關於MYSQL如何解析查詢的額外信息。將在表4.3中討論,但這裏可以看到的壞的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,結果是檢索會很慢

Extra字段解釋

Extra:查詢中每一步實現的額外細節信息,主要會是以下內容。

Distinct:查找distinct 值,當mysql找到了第一條匹配的結果時,將停止該值的查詢,轉爲後面其他值查詢。

Full scan on NULL key:子查詢中的一種優化方式,主要在遇到無法通過索引訪問null值的使用。

Range checked for each record (index map: N):通過 MySQL 官方手冊的描述,當 MySQL Query Optimizer 沒有發現好的可以使用的索引時,如果發現前面表的列值已知,部分索引可以使用。對前面表的每個行組合,MySQL檢查是否可以使用range或 index_merge訪問方法來索取行。

SELECT tables optimized away:當我們使用某些聚合函數來訪問存在索引的某個字段時,MySQL Query Optimizer 會通過索引直接一次定位到所需的數據行完成整個查詢。當然,前提是在 Query 中不能有 GROUP BY 操作。如使用MIN()或MAX()的時候。

Using filesort:當Query 中包含 ORDER BY 操作,而且無法利用索引完成排序操作的時候,MySQL Query Optimizer 不得不選擇相應的排序算法來實現。

Using index:所需數據只需在 Index 即可全部獲得,不須要再到表中取數據。

Using index for group-by:數據訪問和 Using index 一樣,所需數據只須要讀取索引,當Query 中使用GROUP BY或DISTINCT 子句時,如果分組字段也在索引中,Extra中的信息就會是 Using index for group-by。

Using temporary:當 MySQL 在某些操作中必須使用臨時表時,在 Extra 信息中就會出現Using temporary 。主要常見於 GROUP BY 和 ORDER BY 等操作中。

Using where:如果不讀取表的所有數據,或不是僅僅通過索引就可以獲取所有需要的數據,則會出現 Using where 信息。

Using where with pushed condition:這是一個僅僅在 NDBCluster存儲引擎中才會出現的信息,而且還須要通過打開 Condition Pushdown 優化功能纔可能被使用。控制參數爲 engine_condition_pushdown 。

Impossible WHERE noticed after reading const tables:MySQL Query Optimizer 通過收集到的統計信息判斷出不可能存在結果。

No tables:Query 語句中使用 FROM DUAL或不包含任何 FROM子句。

Not exists:在某些左連接中,MySQL Query Optimizer通過改變原有 Query 的組成而使用的優化方法,可以部分減少數據訪問次數。

join優化

需求:統計org_knowledge_department_active_week表(1664萬)與org_knowledge_department_study_month表(280萬)中orgid相同的數據。

org_knowledge_department_active_week結構信息

org_knowledge_department_study_month結構信息

 

EXPLAIN
SELECT
  *
FROM
  org_knowledge_department_active_week t1
  STRAIGHT_JOIN org_knowledge_department_study_month t2
    ON t1.orgid = t2.orgid

此SQL語句執行過程:

  1. 從表t1中讀入一行數據R
  2. 從數據R中取出字段orgid到表t2查找
  3. 取出表t2中滿足條件的數據,與R組成一行,作爲結果集的一部分
  4. 重複執行步驟1至3,直到t1表的末尾

此算法爲Index nested-Loop Join (NLJ): 嵌套查找,並且用上了被驅動表的索引。

t1表

t2表

 

join算法:

Index nested-Loop Join (NLJ):

 

Block Nested-Loop Join (INL):

 

結論

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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