一、explain是什么?
1、 定義
EXPLAIN是mysql中的一個命令,可以模擬優化器執行SQL語句并返回執行計劃。通過執行計劃,我們可以分析查詢語句或表結構的性能瓶頸,從而進行SQL優化。
2、用法
mysql> explain select * from employee;
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | employee | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
通過上面的執行計劃我們可以了解:
表的執行順序數據讀取操作的操作類型哪些索引可以使用哪些索引被實際使用每張表有多少行被優化器查詢
看到這個表,也許你會兩眼一抹黑,這咋看呀?接著往下看,你一定可以從執行計劃中輕松得出以上結果。
二、名詞段解釋
1. id
定義:select查詢的序列號,包含一組數字,表示查詢中執行select子句或操作表的順序。
存在以下三種情況:
id相同,執行順序由上至下
mysql> desc select e.*,p.* from employee e,performance p where p.user_id = e.id;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+
| 1 | SIMPLE | e | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
| 1 | SIMPLE | p | NULL | ALL | NULL | NULL | NULL | NULL | 2 | 50.00 | Using where; Using join buffer (hash join) |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------------+
2 rows in set, 1 warning (0.00 sec)
id不同,如果是子查詢,id序號對遞增,id值越大優先級越高,越先執行
mysql> explain select e.* -> from employee e-> where id = ( select user_id-> from performance-> where performance.score > 80 and performance.year = 2020 and performance.quarter = 2);
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | PRIMARY | e | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where |
| 2 | SUBQUERY | performance | NULL | ALL | NULL | NULL | NULL | NULL | 2 | 50.00 | Using where |
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
2 rows in set, 1 warning (0.01 sec)
id相同而不同(不同的:id越大越先執行;相同的:由上至下按順序執行)
mysql> EXPLAIN SELECT-> e.*, d.depart_name-> FROM employee e,department d-> WHERE-> e.depart_id = d.id-> AND e.id = (-> SELECT user_id-> WHERE-> performance.score > 80-> AND performance. YEAR = 2020-> AND performance. QUARTER = 2-> );
+----+-------------+-------------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
| 1 | PRIMARY | e | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where |
| 1 | PRIMARY | d | NULL | eq_ref | PRIMARY | PRIMARY | 4 | db.e.depart_id | 1 | 100.00 | NULL |
| 2 | SUBQUERY | performance | NULL | ALL | NULL | NULL | NULL | NULL | 2 | 50.00 | Using where |
+----+-------------+-------------+------------+--------+---------------+---------+---------+----------------+------+----------+-------------+
3 rows in set, 1 warning (0.00 sec)
2、select_type
定義:查詢的類型,主要用于區別普通查詢、聯合查詢和子查詢等復合查詢。
SIMPLE:簡單的select查詢,查詢中不包含子查詢和聯合查詢(union)
mysql> explain select * from employee;
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | employee | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
PRIMARY:若查詢中包含任何的子查詢,最外層查詢則標記為PRIMARYSUBQUERY:在select或where列表中包含的子查詢
mysql> explain select e.* -> from employee e-> where id = ( select user_id-> from performance-> where performance.score > 80 and performance.year = 2020 and performance.quarter = 2);
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | PRIMARY | e | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where |
| 2 | SUBQUERY | performance | NULL | ALL | NULL | NULL | NULL | NULL | 2 | 50.00 | Using where |
+----+-------------+-------------+------------+------+---------------+------+---------+------+------+----------+-------------+
2 rows in set, 1 warning (0.01 sec)
DERIVED:在FROM列表中包含的子查詢被標記為(DERIVED),Mysql會遞歸執行這些子查詢,把結果放在臨時表里。
mysql> EXPLAIN select employee.* FROM (SELECT distinct department.id FROM department) s1,employee WHERE s1.id = employee.depart_id;
+----+-------------+------------+------------+-------+---------------+-------------+---------+-----------------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+-------+---------------+-------------+---------+-----------------------+------+----------+-------------+
| 1 | PRIMARY | employee | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where |
| 1 | PRIMARY | <derived2> | NULL | ref | <auto_key0> | <auto_key0> | 4 | db.employee.depart_id | 2 | 100.00 | Using index |
| 2 | DERIVED | department | NULL | index | PRIMARY | PRIMARY | 4 | NULL | 4 | 100.00 | Using index |
+----+-------------+------------+------------+-------+---------------+-------------+---------+-----------------------+------+----------+-------------+
3 rows in set, 1 warning (0.00 sec)
UNION:如果第二個SELECT出現在UNION之后,則標記為UNION;如果UNION包含在FROM子句的子查詢中,外層SELECT被標記為DERIVEDUNION RESULT:從UNION表獲取結果的SELECT
mysql> explain select * from employee union select * from employee_asu;
+----+--------------+--------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+--------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| 1 | PRIMARY | employee | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
| 2 | UNION | employee_asu | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
| NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+--------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
3 rows in set, 1 warning (0.00 sec)mysql> explain select * from (select * from employee union select * from employee_asu) s;
+----+--------------+--------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------+--------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
| 1 | PRIMARY | <derived2> | NULL | ALL | NULL | NULL | NULL | NULL | 4 | 100.00 | NULL |
| 2 | DERIVED | employee | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
| 3 | UNION | employee_asu | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
| NULL | UNION RESULT | <union2,3> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+--------------+------------+------+---------------+------+---------+------+------+----------+-----------------+
4 rows in set, 1 warning (0.00 sec)
3、table
定義:顧名思義,表名。
4、partitions(分區)
定義:顯示表分區的分區名
mysql> explain select * from tk;
+----+-------------+-------+------------+------+---------------+------+---------+---
| id | select_type | table | partitions | type | possible_keys | key | key_len | re
+----+-------------+-------+------------+------+---------------+------+---------+---
| 1 | SIMPLE | tk | p0,p1,p2 | ALL | NULL | NULL | NULL | NU
+----+-------------+-------+------------+------+---------------+------+---------+---
1 row in set, 1 warning (0.00 sec)
5、type
定義:type顯示的是訪問類型,是較為重要的一個指標,結果值從最好到最壞依次為system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > all,常見的有system > const > eq_ref > ref > range > index > all
system:表只有一行記錄(等于系統表),這是const類型的特例,平時不會出現,可忽略不計。
mysql> EXPLAIN select * FROM (SELECT distinct department.id FROM department where id=2) s1;
+----+-------------+------------+------------+--------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+--------+---------------+---------+---------+-------+------+----------+-------------+
| 1 | PRIMARY | <derived2> | NULL | system | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
| 2 | DERIVED | department | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | Using index |
+----+-------------+------------+------------+--------+---------------+---------+---------+-------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
const:表示通過索引一次就找到了,const用于比較primary key或者unique索引,只匹配一行數據,速度很快。
mysql> explain SELECT distinct department.id FROM department where id=2;
+----+-------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | department | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | Using index |
+----+-------------+------------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
eq_ref:唯一性索引掃描,對于每個索引鍵,表中只有一條數據與之匹配,常見于主鍵或唯一索引掃描。
mysql> explain SELECT * from employee,department where employee.depart_id = department.id ;
+----+-------------+------------+------------+--------+---------------+---------+---------+-----------------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+--------+---------------+---------+---------+-----------------------+------+----------+-------------+
| 1 | SIMPLE | employee | NULL | ALL | NULL | NULL | NULL | NULL | 7 | 100.00 | Using where |
| 1 | SIMPLE | department | NULL | eq_ref | PRIMARY | PRIMARY | 4 | db.employee.depart_id | 1 | 100.00 | NULL |
+----+-------------+------------+------------+--------+---------------+---------+---------+-----------------------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
ref:非唯一性索引掃描,返回匹配某個單獨值的所有行
mysql> show index from employee; #查看表索引
+----------+------------+-----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+----------+------------+-----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| employee | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | | YES | NULL |
| employee | 1 | idx_employee_username | 1 | username | A | 0 | NULL | NULL | YES | BTREE | | | YES | NULL |
+----------+------------+-----------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
2 rows in set (0.00 sec)mysql> explain select * from employee where username = "john";
+----+-------------+----------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------+
| 1 | SIMPLE | employee | NULL | ref | idx_employee_username | idx_employee_username | 83 | const | 1 | 100.00 | NULL |
+----+-------------+----------+------------+------+-----------------------+-----------------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.01 sec)
range:只檢索給定范圍的行,使用一個索引來選擇行。key列顯示使用了那個索引,一般是where語句中出現了between、<、>或in等查詢。
mysql> explain select * from employee where id between 1 and 3;
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| 1 | SIMPLE | employee | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 3 | 100.00 | Using where |
+----+-------------+----------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
index:full index scan,全索引樹掃描,通常比all快,因為索引文件比數據文件小很多。
mysql> explain select id from department;
+----+-------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| 1 | SIMPLE | department | NULL | index | NULL | PRIMARY | 4 | NULL | 4 | 100.00 | Using index |
+----+-------------+------------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
all:全表掃描,當數據量達到百萬級別,性能會下降明顯,需要建立索引;當然小數據量的全表掃描是沒有問題的。
mysql> explain select * from department;
+----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | department | NULL | ALL | NULL | NULL | NULL | NULL | 4 | 100.00 | NULL |
+----+-------------+------------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
6、possible_keys
定義:顯示可能應用在這張表中的索引,一個或多個(查詢涉及到的字段若存在索引,則該索引將被列出,但不一定被查詢實際使用)
mysql> explain select id,username,age,salary from employee where username='a';
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | employee | NULL | ref | idx_username_age_salary,idx_username | idx_username_age_salary | 83 | const | 1 | 100.00 | Using index |
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
補充說明:從執行計劃關鍵字possible_keys中可以看出,sql語句執行可能用到idx_username和idx_username_age_salary兩個索引。如果為null,就是沒有可能使用的索引。
7、key
定義:實際使用的索引。如果為null,則沒有使用索引。
常規舉例
mysql> explain select username,age,salary from employee where username = 'a' group by age,salary;
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | employee | NULL | ref | idx_username_age_salary,idx_username | idx_username_age_salary | 83 | const | 1 | 100.00 | Using index |
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
補充說明:possible_keys,可能使用的所以為idx_username,idx_username_age_salary; key,實際使用的索引為idx_username_age_salary
覆蓋索引
看到覆蓋索引也許你兩眼一抹黑,別急,先記住這么一個名詞,繼續往下看。
mysql> explain select username,age,salary from employee;
+----+-------------+----------+------------+-------+---------------+-------------------------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+-------+---------------+-------------------------+---------+------+------+----------+-------------+
| 1 | SIMPLE | employee | NULL | index | NULL | idx_username_age_salary | 93 | NULL | 7 | 100.00 | Using index |
+----+-------------+----------+------------+-------+---------------+-------------------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
補充說明:如果查詢中使用了覆蓋索引,則該索引只會出現在key中,不會出現在possible_keys中。
8、key_len
定義:表示索引中使用的字節數,可通過該列計算查詢中使用的索引長度,在不損失精度的情況下,key_len越短越好。換句話說,key_len顯示的值為索引字段的最大可能長度,即key_len是通過表定義計算而得,不是通過表內檢索出來的,不過具體怎么算出來的沒有研究。
9、ref
定義:顯示索引哪一列別使用了,如果可能的話,是一個常數。指明哪些列或常量被用于查找索引列上的值。
mysql> EXPLAIN SELECT employee.username, employee.age, employee.salary FROM employee, department WHERE employee.id = department.id;
+----+-------------+------------+------------+--------+---------------+---------+---------+------------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+--------+---------------+---------+---------+------------------+------+----------+-------------+
| 1 | SIMPLE | department | NULL | index | PRIMARY | PRIMARY | 4 | NULL | 4 | 100.00 | Using index |
| 1 | SIMPLE | employee | NULL | eq_ref | PRIMARY | PRIMARY | 4 | db.department.id | 1 | 100.00 | NULL |
+----+-------------+------------+------------+--------+---------------+---------+---------+------------------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
補充說明:ref對呀的值為db.department.id,表示數據庫db中的department表中的id列。
mysql> EXPLAIN SELECT username,age,salary FROM employee where username = 'john';
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | employee | NULL | ref | idx_username_age_salary,idx_username | idx_username_age_salary | 83 | const | 1 | 100.00 | Using index |
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
補充說明:username對應的值為john,所以是常量const
10、rows
定義:根據表的統計信息及索引使用情況,大致估算出找到所需的記錄需要讀取的行數。
11、filtered
定義:這個字段表示存儲引擎返回的數據在server層過濾后,剩下多少滿足查詢的記錄數量的比例,注意是百分比,不是具體記錄數。值越大越好。
12、Extra
定義:包含不適合在其它列中顯示但十分重要的的額外信息
Using filesort:說明Mysql使用一個外部索引排序,而不是按照表內的索引進行排序(Mysql中無法使用索引完成的排序操作稱為“文件排序”)。
mysql> EXPLAIN SELECT username,age,salary FROM employee where username = 'john' order by id;
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-----------------------------+
| 1 | SIMPLE | employee | NULL | ref | idx_username_age_salary,idx_username | idx_username_age_salary | 83 | const | 1 | 100.00 | Using index; Using filesort |
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec)
補充說明:雖然使用了idx_username_age_salary索引,但是排序規則不是按照這個索引來的,而是索引文件外排序。因此sql語句的排序規則盡量按照索引的字段來排序,避免文件外排序,降低性能。
using temporary:表示使用了臨時表保存了中間結果,Mysql在對查詢結果排序時使用臨時表,常見于排序order by和分組gruop by。
mysql> explain select age from employee where username in ('john','asd') group by age;
+----+-------------+----------+------------+-------+------------------------------------------------------------+-------------------------+---------+------+------+----------+-------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+-------+------------------------------------------------------------+-------------------------+---------+------+------+----------+-------------------------------------------+
| 1 | SIMPLE | employee | NULL | range | idx_username_age_salary,idx_username,idx_username_departid | idx_username_age_salary | 83 | NULL | 2 | 100.00 | Using where; Using index; Using temporary |
+----+-------------+----------+------------+-------+------------------------------------------------------------+-------------------------+---------+------+------+----------+-------------------------------------------+
1 row in set, 1 warning (0.00 sec)
補充說明:產生臨時表很消耗性能
using index:表示相應的select操作中使用了覆蓋索引,避免訪問了數據行,效率不錯。如果同時出現了using where,表示在索引中查找;如果沒有,表明是從索引中讀取數據,而非查找。
覆蓋索引/索引覆蓋(Covering index):select數據列只需要從索引中就可以全部獲取,不必讀取數據行,換句話說查詢列要被所建的索引覆蓋。
mysql> explain select username,age,salary from employee where username ='john' order by age,salary;
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | employee | NULL | ref | idx_username_age_salary,idx_username | idx_username_age_salary | 83 | const | 1 | 100.00 | Using index |
+----+-------------+----------+------------+------+--------------------------------------+-------------------------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
注意:要想使用覆蓋索引,一定要從select列表中獲取自己想要的列,不可使用select *;如果使用所有列做索引會導致索引過于龐大。
using where:sql語句中使用了where過濾
using join buffer:使用了連接緩存
impossible where:where子句中總是false,不可能查到任何數據
select table optimized away:在沒有group by的情況下,基于索引優化MIN/MAX操作或者對于MyISAM存儲優化count(*)操作,不必等到執行階段在進行計算,執行計劃完成的階段就完成優化。
distinct:優化distinct操作,再找到第一匹配的元組后就停止找同樣值的操作。
總結
以上是生活随笔為你收集整理的Mysql优化之explain你真的会吗?的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。