創建一個表test_explain,并添加入下的數據
mysql> create ?table test_explain( a int primary key, b int);
Query OK, 0 rows affected (0.09 sec)
mysql> insert into test_explain value(1,1),(2,2),(3,3),(4,4),(5,5);
explian中的type字段:表示mysql在表中找到所需行的方式,或者叫訪問類型,常見的取值有ALL,INDEX ,RANGE,REF,EQ_REF,CONST(SYSTEM),NULL
情況1:type=all,全表掃描,mysql遍歷全表來找到匹配的行。
mysql> explain select b from test_explain where b>3\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test_explain
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 5
filtered: 33.33
Extra: Using where
1 row in set, 1 warning (0.01 sec)
情況2:type=index,索引掃描,MYSQL遍歷整個索引來查詢匹配的行
mysql> explain select a from test_explain where a>3\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test_explain
partitions: NULL
type: index
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: NULL
rows: 5
filtered: 40.00
Extra: Using where; Using index
1 row in set, 1 warning (0.01 sec)
情況3:type=range,索引掃描范圍,常見于,>=,between等操作符
mysql> explain select * from test_explain where a>3 and a<5\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test_explain
partitions: NULL
type: range
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: NULL
rows: 1
filtered: 100.00
Extra: Using where
1 row in set, 1 warning (0.01 sec)
情況4:type=ref,非唯一索引掃描或唯一索引掃描的前綴掃描,返回匹配某個單獨值的記錄行
首先為之前創建的表test_explain表的列b增加一個非唯一索引,操作如下:
mysql> alter table test_explain add index(b);,接著的實驗結果為:
mysql> explain select *from test_explain where b=3 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test_explain
partitions: NULL
type: ref
possible_keys: b
key: b
key_len: 5
ref: const
rows: 1
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)
情況5:type=eq_ref,類似ref,區別就在使用的索引是唯一索引,對于每個索引鍵值,表中只有一條記錄匹配;簡單來說,就是在多表連接中使用primary key或者unique index作為關聯條件;注意的前提條件一定是多表連接中;
舉例:新建一個表test_explain2
mysql> create table test_explain2( d int primary key,
-> e char(10) unique key,
-> f int);
Query OK, 0 rows affected (0.08 sec)
mysql> insert into ?test_explain2 values(1,'a',1),(2,'b',2);
Query OK, 2 rows affected (0.04 sec)
Records: 2 ?Duplicates: 0 ?Warnings: 0
mysql> insert into ?test_explain2 values(3,'c',3),(4,'d',4);
Query OK, 2 rows affected (0.02 sec)
Records: 2 ?Duplicates: 0 ?Warnings: 0
接著來進行type=eq_ref的試驗驗證;
mysql> explain SELECT *from test_explain tt,test_explain2 ?yy where tt.a=yy.d \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: yy
partitions: NULL
type: ALL
possible_keys: PRIMARY
key: NULL
key_len: NULL
ref: NULL
rows: 4
filtered: 100.00
Extra: NULL
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: tt
partitions: NULL
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: test.yy.d
rows: 1
filtered: 100.00
Extra: NULL
2 rows in set, 1 warning (0.00 sec)
情況6:type=const/system,單表中最多有一個匹配行,查詢起來非常迅速,所以這個匹配行中的其他列值可以被優化器在當前查詢中當做常量來處理,例如根據主鍵或者唯一索引unique key進行的查詢;
mysql> explain select *from test_explain where a=1\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test_explain
partitions: NULL
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: const
rows: 1
filtered: 100.00
Extra: NULL
1 row in set, 1 warning (0.00 sec)
情況7:type=NULL,不用訪問表或者索引就可以得到結果,如;
mysql> EXPLAIN SELECT 3 \G *************************** 1. row *************************** ? ? ? ? ? ?id: 1 ? select_type: SIMPLE ? ? ? ? table: NULL ? ?partitions: NULL ? ? ? ? ?type: NULL possible_keys: NULL ? ? ? ? ? key: NULL ? ? ? key_len: NULL ? ? ? ? ? ref: NULL ? ? ? ? ?rows: NULL ? ? ?filtered: NULL ? ? ? ? Extra: No tables used 1 row in set, 1 warning (0.00 sec)