-Innerhashjoin(a.depno=b.depno)(cost=2.60rows=6)-Tablescanona(cost=0.15rows=6)-Hash-Indexscanonbusingname(cost=0.55rows=3)
1rowinset(0.03sec)那有没有更高级的功能呢,在每一个步骤展示预估执行时间,这个在MySQL8.0.18同样支持,在explain后面加上ANALYZE就可以mysqlEXPLAINANALYZEselecta.name,a.depno,b.namefromt_test1ainnerjoint_test2bona.depno=b.depno;
-Innerhashjoin(a.depno=b.depno)(cost=2.60rows=6)(actualtime=3...3.rows=6loops=1)-Tablescanona(cost=0.15rows=6)(actualtime=0...0.rows=6loops=1)-Hash-Indexscanonbusingname(cost=0.55rows=3)(actualtime=1...1.rows=3loops=1)
1rowinset(0.03sec)在这里观察仔细的小伙伴,会发现,actualtime有两个时间,这两个时间,我解释一下Actualtime获取第一行的消耗的时间(inmilliseconds)Actualtime获取第所有行的消耗的时间(inmilliseconds)可能有的小伙伴会问,actualtime=1...1.rows=3loops=1),为什么获取第一条记录要1.,而获取3条记录不是5.,而是1.,这是因为,这3条记录都在一个page页,数据库最小读取单位是page页,一次IO就能把3条记录读取,后面的动作都是在内存里操作,基本不消耗时间。在这里我再延伸讲解一下,数据库的二级索引,大家还是看上面的sql执行计划selecta.name,a.depno,b.namefromt_test1ainnerjoint_test2bona.depno=b.depnomysqlshowcreatetablet_test2\G;***************************1.row***************************Table:t_test2CreateTable:CREATETABLE`t_test2`(`depno`int(11)NOTNULL,`name`char(20)DEFAULTNULL,PRIMARYKEY(`depno`),KEY`name`(`name`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COLLATE=utf8mb4__ai_ci1rowinset(0.02sec)不知道小伙伴们,发现没有,possible_keys为PRIMARY,但是key却是name,而不是depno。很奇怪吧,这里有2个原因原因一:在select要查询的列是t_test2表的name列原因二:join条件是主键列depno在这里就不得不先说一下mysql的二级索引,在mysql数据中所有的数据都是存储在索引中,主键基本都是聚簇索引,存储是记录行,二级索引,存储的是索引列值和主键值。下面用图来说明回到上面sql语句的执行计划,为什么用了name列的二级索引,这是因为二级索引里存储了name和depno两个值,sql语句只需要扫描name索引,就可以获取需要的数据,而不用再去访问主键的聚簇索引。