Type訪問類型,效率低到高如下:
all < index < range < index_subquery < unique_subquery < index_merge < ref_or_null < ref < eq_ref < const < system
1. all
全表掃描,Mysql遍歷全表來找到匹配的行,在大數據量的時候效率極低。
2. index
索引全掃描。Mysql遍歷整個索引來查詢匹配的行。根據Extra的內容分以下幾種情況:
Using Index:表示相應的select操作中使用了覆蓋索引(Covering Index),避免了訪問表的數據行,效率高。使用索引來直接獲取列的數據,而不需回表。如果同時出現Using where,表明索引被用來執行索引鍵值的查找。 如果沒用同時出現Using where,表明索引用來讀取數據而非執行查找動作。Using Index就是隻需使用索引就可以查到所需的字段。
覆蓋索引(Covering Index):也叫索引覆蓋。就是select列表中的字段,只用從索引中就能獲取,不必根據索引再次讀取數據文件,換句話說查詢列要被所建的索引覆蓋。
注意:
a、如需使用覆蓋索引,select列表中的字段只取出需要的列,不要使用select *
b、如果將所有字段都建索引會導致索引文件過大,反而降低crud性能
Using Where:使用了where篩選條件。
Using Index & Using Where:查找使用了索引,但是需要的數據都在索引列中能找到,所以不需要回表查詢數據,即是利用索引查找鍵值。
Using filesort:Using filesort通常出現在order by,當試圖對一個不是索引的字段進行排序時,mysql就會自動對該字段進行排序,這個過程就稱爲“文件排序”。
Using temporary:表示在查詢過程中產生了臨時表用於保存中間結果。mysql在對查詢結果進行排序時會使用臨時表,常見於group by。group by的實質是先排序後分組,同order by一樣,group by和索引息息相關。出現Using temporary意味着產生了臨時表存儲中間結果並且最後刪掉了該臨時表,這個過程很消耗性能。
會產生臨時表的情況:
- 對一個沒有索引的字段進行分組,會產生臨時表。
- 當order by子句和group by子句的字段不同時就會產生臨時表。
- 當用left join時,若order by子句和group by子句都來自於從表時會產生臨時表。
不會產生臨時表的情況:
- 對一個有索引的字段進行分組就不會產生臨時表。
- 當order by子句和group by子句的字段相同時不會產生臨時表。
Null:查詢列有些不是索引,需要回表來查詢未被索引覆蓋的字段(不是純粹用了索引,也不是完全沒用到索引)
3. range
索引範圍掃描。常見於:<、<=、>、>=、between
4. index_subquery
用於in形式子查詢使用到了輔助索引或者in常數列表,子查詢可能返回重複值,可以使用索引將子查詢去重。
5. unique_subquery
用於where中的in形式子查詢,子查詢返回不重複值。
6. index_merge
使用了索引合併優化。(對多個索引分別進行了條件的查詢,最後對這幾個查詢的結果進行合併交集運算)
7. ref_or_null
類似ref。區別是他會額外的搜索包含null的記錄,他會對其進行一些優化。(例如:select * from m_user where age = 18 and name is null)
8. ref
使用非唯一索引掃描或唯一索引的前綴掃描,返回匹配某個單獨值的記錄。
9. eq_ref
類似ref,區別就在使用的索引是唯一索引,對於每個索引鍵值,表中只有一條記錄匹配;簡單來說,就是多表連接中使用primary key或者unique index作爲關聯條件。
10. const
查詢條件是主鍵或者非NULL的UNIQUE索引,因此結果只有一條,同時優化過程中查詢列值會轉成常量。
11. system
表中數據只有一行的情況。
12. NULL
不用訪問表就可以直接得到結果。(例如:SELECT 1)