11<!-- START doctoc generated TOC please keep comment here to allow auto update -->
22<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
3- ** Table of Contents ** * generated with [ DocToc ] ( https://github.com/thlorenz/doctoc ) *
3+
44
55- [ id] ( #id )
66- [ select_type] ( #select_type )
2929 - [ using temporary] ( #using-temporary )
3030 - [ filesort] ( #filesort )
3131 - [ using join buffer] ( #using-join-buffer )
32+ - [ 参考资料] ( #%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99 )
3233
3334<!-- END doctoc generated TOC please keep comment here to allow auto update -->
3435
@@ -89,7 +90,7 @@ where blog_id = (
8990
9091三个表依次嵌套,发现最里层的子查询 ` id ` 最大,最先执行。
9192
92- ![ explain-id ] ( https://gitee.com/tysondai/img/raw/master/explain-id.png )
93+ ![ ] ( https://gitee.com/tysondai/img/raw/master/explain-id.png )
9394
9495## select_type
9596
@@ -105,13 +106,13 @@ where blog_id = (
105106
106107查询的表名,并不一定是真实存在的表,有别名显示别名,也可能为临时表。当from子句中有子查询时,table列是 ` <derivenN> ` 的格式,表示当前查询依赖 id为N的查询,会先执行 id为N的查询。
107108
108- ![ explain-table ] ( https://gitee.com/tysondai/img/raw/master/image-20210804083523885.png )
109+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210804083523885.png )
109110
110111## partitions
111112
112113查询时匹配到的分区信息,对于非分区表值为` NULL ` ,当查询的是分区表时,` partitions ` 显示分区表命中的分区情况。
113114
114- ![ explain-partitions ] ( https://gitee.com/tysondai/img/raw/master/image-20210802022931773.png )
115+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210802022931773.png )
115116
116117## type
117118
@@ -121,25 +122,25 @@ where blog_id = (
121122
122123当表仅有一行记录时(系统表),数据量很少,往往不需要进行磁盘IO,速度非常快。比如,Mysql系统表proxies_priv在Mysql服务启动时候已经加载在内存中,对这个表进行查询不需要进行磁盘 IO。
123124
124- ![ explain-system ] ( https://gitee.com/tysondai/img/raw/master/image-20210801233419732.png )
125+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210801233419732.png )
125126
126127### const
127128
128129单表操作的时候,查询使用了主键或者唯一索引。
129130
130- ![ explain-const ] ( https://gitee.com/tysondai/img/raw/master/explain-const.png )
131+ ![ ] ( https://gitee.com/tysondai/img/raw/master/explain-const.png )
131132
132133### eq_ref
133134
134135** 多表关联** 查询的时候,主键和唯一索引作为关联条件。如下图的sql,对于user表(外循环)的每一行,user_role表(内循环)只有一行满足join条件,只要查找到这行记录,就会跳出内循环,继续外循环的下一轮查询。
135136
136- ![ explain-eq_ref ] ( https://gitee.com/tysondai/img/raw/master/image-20210801232638027.png )
137+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210801232638027.png )
137138
138139### ref
139140
140141查找条件列使用了索引而且不为主键和唯一索引。虽然使用了索引,但该索引列的值并不唯一,这样即使使用索引查找到了第一条数据,仍然不能停止,要在目标值附近进行小范围扫描。但它的好处是不需要扫全表,因为索引是有序的,即便有重复值,也是在一个非常小的范围内做扫描。
141142
142- ![ explain-ref.png ] ( https://gitee.com/tysondai/img/raw/master/explain-ref.png )
143+ ![ ] ( https://gitee.com/tysondai/img/raw/master/explain-ref.png )
143144
144145### ref_or_null
145146
@@ -149,31 +150,31 @@ where blog_id = (
149150
150151使用了索引合并优化方法,查询使用了两个以上的索引。新建comment表,id为主键,value_id为非唯一索引,执行` explain select content from comment where value_id = 1181000 and id > 1000; ` ,执行结果显示查询同时使用了id和value_id索引,type列的值为index_merge。
151152
152- ![ type-index_merge ] ( https://gitee.com/tysondai/img/raw/master/image-20210802001215614.png )
153+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210802001215614.png )
153154
154155### range
155156
156157有范围的索引扫描,相对于index的全索引扫描,它有范围限制,因此要优于index。像between、and、'>'、'<'、in和or都是范围索引扫描。
157158
158- ![ explain-range.png ] ( https://gitee.com/tysondai/img/raw/master/explain-range.png )
159+ ![ ] ( https://gitee.com/tysondai/img/raw/master/explain-range.png )
159160
160161### index
161162
162163index包括select索引列,order by主键两种情况。
163164
1641651 . order by主键。这种情况会按照索引顺序全表扫描数据,拿到的数据是按照主键排好序的,不需要额外进行排序。
165166
166- ![ type-index-orderBy ] ( https://gitee.com/tysondai/img/raw/master/image-20210801225045980.png )
167+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210801225045980.png )
167168
1681692 . select索引列。type为index,而且extra字段为using index,也称这种情况为索引覆盖。所需要取的数据都在索引列,无需回表查询。
169170
170- ![ type-index-selectIndexColumn ] ( https://gitee.com/tysondai/img/raw/master/image-20210801225942948.png )
171+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210801225942948.png )
171172
172173### all
173174
174175全表扫描,查询没有用到索引,性能最差。
175176
176- ![ explain-all ] ( https://gitee.com/tysondai/img/raw/master/explain-all.png )
177+ ![ ] ( https://gitee.com/tysondai/img/raw/master/explain-all.png )
177178
178179## possible_keys
179180
@@ -221,13 +222,13 @@ CREATE TABLE `t_orderdetail` (
221222
222223查询的列未被索引覆盖,where筛选条件非索引的前导列。对存储引擎返回的结果进行过滤(Post-filter,后过滤),一般发生在MySQL服务器,而不是存储引擎层。
223224
224- ![ extra-using-where ] ( https://gitee.com/tysondai/img/raw/master/image-20210802232729417.png )
225+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210802232729417.png )
225226
226227### using index
227228
228229查询的列被索引覆盖,并且where筛选条件符合最左前缀原则,通过** 索引查找** 就能直接找到符合条件的数据,不需要回表查询数据。
229230
230- ![ extra-using-index ] ( https://gitee.com/tysondai/img/raw/master/image-20210802232357282.png )
231+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210802232357282.png )
231232
232233### Using where&Using index
233234
@@ -237,29 +238,29 @@ CREATE TABLE `t_orderdetail` (
237238
238239- where筛选条件不符合最左前缀原则
239240
240- ![ extra-using-where&index ] ( https://gitee.com/tysondai/img/raw/master/image-20210802233120283.png )
241+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210802233120283.png )
241242
242243- where筛选条件是索引列前导列的一个范围
243244
244- ![ extra-using-where&index ] ( https://gitee.com/tysondai/img/raw/master/image-20210802233455880.png )
245+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210802233455880.png )
245246
246247### null
247248
248249查询的列未被索引覆盖,并且where筛选条件是索引的前导列,也就是用到了索引,但是部分字段未被索引覆盖,必须回表查询这些字段,Extra中为NULL。
249250
250- ![ extra-null ] ( https://gitee.com/tysondai/img/raw/master/image-20210802234122321.png )
251+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210802234122321.png )
251252
252253### using index condition
253254
254255索引下推(index condition pushdown,ICP),先使用where条件过滤索引,过滤完索引后找到所有符合索引条件的数据行,随后用 WHERE 子句中的其他条件去过滤这些数据行。
255256
256257不使用ICP的情况(` set optimizer_switch='index_condition_pushdown=off' ` ),如下图,在步骤4中,没有使用where条件过滤索引:
257258
258- ![ no-icp ] ( https://gitee.com/tysondai/img/raw/master/no-icp.png )
259+ ![ ] ( https://gitee.com/tysondai/img/raw/master/no-icp.png )
259260
260261使用ICP的情况(` set optimizer_switch='index_condition_pushdown=on' ` ):
261262
262- ![ icp ] ( https://gitee.com/tysondai/img/raw/master/icp.png )
263+ ![ ] ( https://gitee.com/tysondai/img/raw/master/icp.png )
263264
264265下面的例子使用了ICP:
265266
@@ -268,17 +269,11 @@ explain select user_id, order_id, order_status
268269from t_order where user_id > 1 and user_id < 5 \G;
269270```
270271
271- ![ icp-demo ] ( https://gitee.com/tysondai/img/raw/master/image-20210803084617433.png )
272+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210803084617433.png )
272273
273274关掉ICP之后(` set optimizer_switch='index_condition_pushdown=off' ` ),可以看到extra列为using where,不会使用索引下推。
274275
275- ![ no-icp-demo] ( https://gitee.com/tysondai/img/raw/master/image-20210803084815503.png )
276-
277- > [ 索引下推例子] ( https://www.cnblogs.com/Chenjiabing/p/12600926.html )
278- >
279- > [ 索引下推图解] ( https://www.cnblogs.com/zengkefu/p/5684101.html )
280- >
281- > [ 索引下推优化] ( https://www.cnblogs.com/zengkefu/p/5684101.html )
276+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210803084815503.png )
282277
283278### using temporary
284279
@@ -292,20 +287,16 @@ from t_order where user_id > 1 and user_id < 5\G;
292287- select 查询字段不全是索引字段
293288- select 查询字段都是索引字段,但是 order by 字段和索引字段的顺序不一致
294289
295- ![ explain-filesort ] ( https://gitee.com/tysondai/img/raw/master/image-20210804084029239.png )
290+ ![ ] ( https://gitee.com/tysondai/img/raw/master/image-20210804084029239.png )
296291
297292### using join buffer
298293
299294Block Nested Loop,需要进行嵌套循环计算。两个关联表join,关联字段均未建立索引,就会出现这种情况。比如内层和外层的type均为ALL,rows均为4,需要循环进行4* 4次计算。常见的优化方案是,在关联字段上添加索引,避免每次嵌套循环计算。
300295
301296
302297
303- 本文参考了一些优秀的博客,感兴趣的可以了解下:
298+ ## 参考资料
304299
305300- [ Explain执行计划] ( https://juejin.cn/post/6844904163969630221#heading-7 )
301+ - [ 索引下推例子] ( https://www.cnblogs.com/Chenjiabing/p/12600926.html ) | [ 索引下推图解] ( https://www.cnblogs.com/zengkefu/p/5684101.html ) | [ 索引下推优化] ( https://www.cnblogs.com/zengkefu/p/5684101.html )
306302
307-
308-
309- 码字不易,如果本文写的不错,可以点个赞,让我知道,支持我写出更好的文章!
310-
311- 我是程序员大彬 ,专注Java后端硬核知识分享,欢迎大家关注~
0 commit comments