MySQL 使用 explain + sql 語句查看 執行計划,該執行計划不一定完全正確但是可以參考。
EXPLAIN SELECT * FROM user WHERE nid = 3;

| select_type | 說明 |
|---|---|
| SIMPLE | 簡單查詢 |
| PRIMARY | 最外層查詢 |
| SUBQUERY | 映射為子查詢 |
| DERIVED | 子查詢 |
| UNION | 聯合 |
| UNION RESULT | 使用聯合的結果 |
table : 正在訪問的表名
| type | 說明 |
|---|---|
| ALL | 全數據表掃描 |
| index | 全索引表掃描 |
| RANGE | 對索引列進行范圍查找 |
| INDEX_MERGE | 合並索引,使用多個單列索引搜索 |
| REF | 根據索引查找一個或多個值 |
| EQ_REF | 搜索時使用primary key 或 unique類型 |
| CONST | 常量,表最多有一個匹配行,因為僅有一行,在這行的列值可被優化器剩余部分認為是常數,const表很快,因為它們只讀取一次。 |
| SYSTEM | 系統,表僅有一行(=系統表)。這是const聯接類型的一個特例。 |
性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
性能在 range 之下基本都可以進行調優
possible_keys : 可能使用的索引
key : 真實使用的
key_len : MySQL中使用索引字節長度
rows : mysql 預估為了找到所需的行而要讀取的行數
| extra | 說明 |
|---|---|
| Using index | 此值表示mysql將使用覆蓋索引,以避免訪問表。 |
| Using where | mysql 將在存儲引擎檢索行后再進行過濾,許多where條件里涉及索引中的列,當(並且如果)它讀取索引時,就能被存儲引擎檢驗,因此不是所有帶where子句的查詢都會顯示“Using where”。有時“Using where”的出現就是一個暗示:查詢可受益於不同的索引。 |
| Using temporary | mysql 對查詢結果排序時會使用臨時表。 |
| Using filesort | mysql會對結果使用一個外部索引排序,而不是按索引次序從表里讀取行。mysql有兩種文件排序算法,這兩種排序方式都可以在內存或者磁盤上完成,explain不會告訴你mysql將使用哪一種文件排序,也不會告訴你排序會在內存里還是磁盤上完成。 |
| Range checked for each record(index map: N) | 沒有好用的索引,新的索引將在聯接的每一行上重新估算,N是顯示在possible_keys列中索引的位圖,並且是冗余的 |
limit
limit 匹配后就不會繼續進行掃描
mysql> SELECT * FROM user WHERE email = 'klvchen123@126.com' LIMIT 1;
+-----+------------+--------------------+-------+
| nid | name | email | extra |
+-----+------------+--------------------+-------+
| 123 | klvchen123 | klvchen123@126.com | 123 |
+-----+------------+--------------------+-------+
1 row in set (0.01 sec)
正確使用索引
- 使用 like 語句時,%在右邊才會使用索引。
沒用使用索引

使用索引

- or 條件中有未建立索引的列才,索引失效
沒用使用索引

使用索引

- 條件的類型不一致
沒用使用索引

使用索引

- != 號
沒用使用索引

例外:如果是主鍵,則會走索引 - > 號
沒用使用索引

例外:如果是主鍵或索引是整數類型,則會走索引 - order by
沒用使用索引

例外:如果 order by 是主鍵或索引是整數類型,則會走索引 - 組合索引
遵循最左前綴
# 若 name 和 email 組成組合索引
create index ix_name_email on user(name,email);
name and email -- 使用索引
email and name -- 不使用索引
name -- 使用索引
email -- 不使用索引
沒用使用索引


