Mysql 的执行计划中有项不起眼但同时很让人产生误解的东西,其中有一项就是Extra, 这一列放在了最后,并且意思是额外的辅助信息,似乎是最不起眼的一个项。
id |
select_id |
The SELECT identifier |
select_type |
None | The SELECT type |
table |
table_name |
The table for the output row |
partitions |
partitions |
The matching partitions |
type |
access_type |
The join type |
possible_keys |
possible_keys |
The possible indexes to choose |
key |
key |
The index actually chosen |
key_len |
key_length |
The length of the chosen key |
ref |
ref |
The columns compared to the index |
rows |
rows |
Estimate of rows to be examined |
filtered |
filtered |
Percentage of rows filtered by table condition |
Extra |
None | Additional information |
Extra会有哪些值呢? 官方列出了20多种,我一一看了下,大部分都是特别好懂,有兴趣可以点击上面链接去官网查看,我不在一一详列。 其中最常见的莫过于以下几种了。
Using index
(JSON: using_index
)
The column information is retrieved from the table using only information in the index tree without having to do an additional seek to read the actual row. This strategy can be used when the query uses only columns that are part of a single index. (这个用一句话解释,就是覆盖索引,不需要读取数据文件)
例如:
语句1:select id from T where id =1;(id 为primary key)
可是如果将查询改为:
alter table T add index idx_name('name');
语句2: select name from t where name='test';
Extra就会变为 Using where; Using index
为什么呢?很明显语句2也是走索引查询,也是覆盖索引。我们来看看官方的E文
Using where
(JSON: attached_condition
text)
A WHERE
clause is used to restrict which rows to match against the next table or send to the client. Unless you specifically intend to fetch or examine all rows from the table, you may have something wrong in your query if the Extra
value is not Using where
and the table join type is ALL
or index
.
join type 是 ALL 或者 index都是走全表扫描,只是一个扫表,一个扫索引。 那么Using where 的意思在这里似乎也解释的很明朗,那就是用来过滤的。 可是为什么语句1 没有用Using where呢? 其实我认为这只是一个理解的问题。 并不代表语句一没有用where去过滤定位, 而是唯一索引可以一次性定位出固定的值,而非唯一索引只能找到索引的页码,具体的值还得根据Where条件继续去遍历索引。
File sort: 并不代表文件排序
这两个定义确实很容易给人造成误解,所以我的建议是不要在这两个信息里面做过多的想像。前面的项目信息更有参考价值。