00:00
好,那么接着的话呢,我们来看下一个啊,下一个呢,这叫ref,这个ref话呢,也不是特别难啊,就是当我们呢,去使用这个索引力等值的这个查询的时候呢,我们与索引列呢,进行等值匹配这个对象的一个信息啊,对象的一个信息,那其实呢,跟我们前面的讲这个typeb当中有一些具体这个值呢,它是能够匹配在一起的啊这块我们一讲呢,大家就能明白了,你比如说呢,我们呢,Select from s1 where呢,K1等于A,那我们那K上呢,是不是就有个索引,然后呢,它的是不是进行了个等值的一个比较,还是一个常量的对吧?好,那这是我们去一执行这个呢,对应的一个普通的一个二级索引的话呢,诶普通的一个索引的话呢,这个时候呢,就是ref,那这时候呢,我们这个ref呢,它跟一个常量进行比较,所以呢这个呢,就是一个cost。啊,好理解是吧,然后接下来我们再看这个啊,Explain一下。值的话呢,我们是有两个表,然后这个呢,是一个等值的一个情况,那外边的话呢,是一个哦,然后里边的话呢,是不是跟我们,呃,你这是一个主键了啊,诶相当于一个具体的确定的值去比较的,这个呢叫EQ啊EQREF,然后这时候呢,我们比较的是谁呢?就是我们S2的这个ID呢,它跟S1具体的这个ID呢,进行比较的啊,是个等值的一个情况嘛,所以呢,这块的具体写出来啊,把我们这个数据库呢,你看都写出来了,I硅股DB一点里边的这个ID。
01:18
是吧,哎,就这个意思啊,这个呢是我们外层啊,外层这块呢,它就没有了啊OK,然后再看这个啊,我们选中了做一个执行这个的区别就在于的话呢,我们在这个SE这块呢,加了一个函数。啊,加了函数以后的话呢,这个位置它写的啊,首先我们看这个位置啊,这个呢是我们S2点这个K1,这个K1的话呢,上面也有一个对应的是是一个缩引对吧?诶使用的叫re EF了啊ref这有一个普通的一个索引,然后这块呢,对应的我们这个呃是一个什么呢?它就不是直接写成叫艾特硅谷d be一下的S1了啊的这个KE1了啊因为我们这块呢,整体上来讲是一个函数来作用的,所以这就是funk表示的是一个函数的意思。啊,OK行,嗯,这个呢,大家做一个了解就行啊,就是相当于可以辅助着我们这个tap当中的一些场景呢,大家去理解就OK了,然后呢,我们再看下边这个,这个呢叫Rose。
02:08
啊,这个Rose是这个行数的意思啊,不是那个玫瑰啊Rose了,这个Rose呢,和我们这个filter的啊,这两个呢,我们经常呢,可以联合在一起呢,去进行查看,这个Rose呢,就是预估的啊,需要读取的这个记录的条目数。啊,这个预估的需要读取的条目数,那条目数越小越好,你比如我们这个K呢,等于一个啊123,那就找到那一条记录,那是不是就特别棒了,那越小越好,那这时候呢,你看我们查询来选中呢,做个执行,那我们这个时候呢,查询的这个结果是382条记录,就是预估呢,我们会找到这么多条这个记录,那实际上找了多少呢?那我们把它的选中了,诶把这个我们谁来给它选中,咱们执行一下。啊,实际上的话呢,你看我们找的还真是382条记录,对吧?哎,就这样的一个道理,那我们为什么说这个值越小越好呢?那越小的话呢,我们相应对应的这个记录呢,它就更有可能是不是在同一个页当中,那只要在同一页当中,我们进行的IO的次数呢,是不是可以就更少一些,对吧。
03:04
那就这个意思啊。当然了,这个跟我们具体从哪加载的也有关系啊,缓存中这个速度大于内存中,大于我们的磁盘中啊,当然了,磁盘中呢,也考虑你要是一个顺序IO的话呢,性能性能也很高是吧?这里一说就复杂了,咱们前面呢都讲过啊,好拉回来,那这呢就是我们这个,呃,预估呢,你查询到这个条目数啊,越小就是越精准啊,对应的页呢就越少啊。好,然后呢,我们再看后边这个呢,叫filter的啊,Filter就是个过滤的意思啊,像我们刚才这块呢,说我找他大于Z的啊,预估呢是有382条记录,然后这个filter呢,是100这个意思呢,就是100%的意思,相当于我们这么多数据里边100%呢,都是满足我们这个体面要求的,那就是这个意思啊,经过搜索之后呢,剩余的记录的承诺数的一个百分比,这个百分比的话呢,是越高越好吗?应该是的,对吧,啊越高越好,为什么这么讲呢?你比如说呢,咱们就这样啊,固定下来,咱们现在最终结果呢,假设呢,就能查询到40条记录,那如果说你是一个100%的,相当于这个预估的Rose呢,就是40,结果呢,就还是确实呢,就是这40条,这就相当于是100%了,那如果说你要是10%的话呢,是不是相当于我们这个呢,对应过来是不是就是400条记录啊。
04:13
哎,那最终结果你看都是40条,但是呢,你一个是从400条记录里边呢去找的,一个是从四条记录里边去找的,那显然呢,从这里边去找的对应的这个页呢,是不是就更少一些,对吧?啊,肯定是要更好一点,所以说呢,我们这个百分比呢,越高是不是就越好一些啊,就这个意思说,如果呢,你使用的是这个索引查询的这个单表扫描的话,那么计算时需要估计除满足除使用到对应的索引的所有条以外的其他。哎,所的条件那个记录有多少条啊,说的有点绕,什么意思啊,你看这个。咱们刚才呢,在这个plan的时候呢,是不是这个叫382条记录,然后你看我们这又多了一个按的操作来走起。啊,大家看诶我们这时候呢,是不是也是382条记录啊,其实这块呢,诶相当于用到了我们这个索引了,那我们呢,一共呢,定位到这个数据呢,应该是三百三百八十二条记录,但是呢,这个比例呢是10%啊相当于我们382呢乘以十是不是大概就是38条记录左右,对吧?呃,这这个10%呢,主要是相当于刻画的就是我们有382条记录呢,是满足这个条件的,那同时的话呢,如果在这个基础上呢,再满足这个条件,大概的比例呢,是有10%这样的一个情况。
05:24
啊,那么这个呢,它呢,其实主要就是受我们这个字段的一个影响,对吧,哎,就这个意思。好,下边接着说说呢,对于咱们单表查询来说呀,这个filter这个意义啊,它没有太大啊,没有太大这个意义啊,我们更关注的是这个连接查询当中,驱动表对应的这个执行计划当中,这个叫filter,这个值它决定了我们被驱动表呢,它要执行的一个次数啊大家来看我们这个例子,来我们这块呢,做一个explain,那这里边有两个表,所以呢是两行记录,然后呢,这是一个select,所以都是一对吧,哎,然后呢,你看我们通过这个驱动表的话呢,我们去跟这个S2呢去连接啊,那连接的话呢,我们是,诶这里边取一条记录跟它里边去连接,现在这是Y层的是一个O,那里边的话呢,这是一个有索引的,然后它对接的是不是这个ref,就是我们外层的S1.k啊,这呢应该都很好理解是吧,Ref的啊,是一个等值的这种情况啊,这都很好理解,那么这时候我们外边这个记录跟他去给他这个值的时候啊,就是因为这呢不是都给到诶我们外层这个S1这个值给一个给里边的给给他去操作是吧,再给一个给他给S2呢去操作,这个被驱动表去使用,那我们到底给多少次呢?那我们。
06:30
在这块就看到了说外层啊,诶我们目标定位的大概数据呢,是9895条,然后呢,诶在我们满足这样的一个条件的情况下呢,说我大概能有10%呢,是满足的,那9895乘以10%是不是989条记录,那相当于大概呢,我会有989个这个数呢,来让他们去执行这个情况。哎,相当于这个我们S2的话呢,大概要执行这么多次是吧,985这么多次,哎这个的话呢,就有意义,你这个值要大的话呢,这个执行的次数是不是要更多一些。啊,就是这个道理。
07:01
好,这呢,就咱们这个叫filter的啊,那么再回过来,咱们针对于说大家比较关注的点呢,一个是咱们的叫诶tap啊,是比较重要的一个点,然后这个叫K的话呢,这个针对我们联合索引的话呢,是比较有意义的,还有这个我们提到这个Rose啊,通常我们也结合着这叫filter的,我们去看这个值的话呢,相当于是越小越好,这个的话呢,是不是越大越好,对吧,然后接下来的话呢,我们再看一看这个叫extra啊。好,接着呀,咱们来看关于我们这个plan的最后一个字段了啊,这个呢也是比较重要的一个字段啊,虽然说呢,它叫做act啊,就是额外的有点像我们讲这个流程控制里边这个叫default或者叫else是吧,这样的这个场景一样属于一个备胎一样啊备注是吧?但其实呢,我们这里边的X呢,还是能够我们提供很多额外的信息的啊,这个呢,显示的还是比较重要的一些信息啊,所以这个呢,大家也需要能够去解读,需要呢去关注,那么通过这些额外的信息啊,我们可以更准确的去理解MYSQL到底呢将如何执行给定的查询语句。
08:01
哇,原来这么重要的话呢,竟然放到这个X里边了是吧?诶这里边呢,它更多的像是一句话啊,那我们到时候呢,演示一下,大家就发现了,说这个麦SCO啊,它提供的额外信息啊,有好几十个啊,确实呢还是挺多的啊,通过实际呢,再去呃编这些例子当中呢,这个确实场景稍微你调换一个字段,调换一个这个呃等于的这个值,你发现呢,它这个X呢就变了,诶所以他这个信息量很大,我们这里呢,主要给大家去列举一些比较常见的一些场景。好,那么这样的话呢,咱们就直接定位到咱们这这个位置啊就可以了啊,你会发现呢,你看我们的X呢,是不是占据的这个呃,比例呢也比较大的是吧?好我们看一下,呃,首先的话呢,这里边说当查询语句当中没有from句的时候呢,我们就不会去提示这个额外的信息啊,SELECT1啊,这就是查询一下我们这个,呃,直接把你这个数据查完了就得了,这是最简单的一个结构了,对吧,所以说没有任何表呢被使用了啊,这个呢,一看就理解啊,好就过了,下一个说呢,查询语句中这个where子句永远为false这个场景啊,你像我们这个一不等于一啊,那一永远不可能等于一,所以呢,你要有这个过滤条件,这个结果呢,也不会有数据。
09:05
诶所以呢,我们这个查询优化器呢,在优化的时候呢,你看我们针对这个where呢,去考虑的时候,发现这个结果这个呢,就肯定是个force,诶我们会提示呢,说impossible啊,不可能的这样的一个过滤条件啊,就这样的一个道理啊。所以这个呢,我们要是真正去查询的话呢,它也不会有任何的数据对吧?行啊,你看这个时候呢,我们关于table这块,你看是都都没列,那为啥没列啊,是不是没有意义啊啊,你这个呢,我就没有必要呢跟你去整这么复杂了,你这个啥玩意儿也没有是吧?哎,就这个意思啊,查不到任何的数据,接着说,当我们使用全表扫描来执行对某一个表的查询的时候啊,全表扫描就意味着你看我们这时候呢,就没有索引了,对吧?那并且呢,该语句的这个where子句中啊,有针对于该表的一个搜索条件的时候。啊,针对该表这个搜索条件的时候呢,在I里边呢,会提出上述的这个信息啊,这个呢,就相当于是就使用一个where啊这样个意思啊,没有任何的索引是吧?哎,就是using where样的一个场景,好,下边说当我们使用索引来访问某一个表的这个查询的时候,啊,那么在该表这个V中,除了呢,诶包含诶这个你看就就先说这个事吧,我们这时候呢,你看where啊,K1等于A,那这个K1等于A的话呢,这显然呢,是不是一个索引了,那这个场景下,你看这块有啥呢?
10:21
啊,我们执行一下,看什么也没有。啊,什么也没有啊,他就是使用我们这样一个索引,那就是用我们这个啊IDXK啊去用就完了是吧,那么在这个基础上呢,他又多了一个啊说一个没有是不是索引的这样的一个过滤条件啊,啊那么这个时候呢,它呈现的点呢,哎,我们走起啊叫也叫using where。啊,也叫这个U型V啊,因为你看本身我们这块去看的话呢,什么也没有,是不是类似于我们这样的一个场景是吧,哎,就是相当于单独的还是一个普通的一个字段啊做的一个呃过滤。好,再往下说呢,当这个查询这个列表中有这个meanin,或者有这个max这种聚合函数的时候,但是呢,并没有符合我们V尔子集中这个搜索条件的记录的时候,哎,我们呢,就会显示的这种额外信息啊,这个里边我写的这个K1呢,是等于这个值啊,这个呢,大家要注意一下,就是我们这个一呢,其实表中不存在这个记录,比如我们起来from一下我们这个S1说where呢,我们这个K1呢,等于哎,我把这个粘过来在我们这个啊。
11:19
啊,这个我我我就直接这样执行了啊,在我们这个select查询的时候呢,这个表中啊,根本就没有这条记录,那么这条记录都没有,那你说我们再去这个本身它有个索引嘛,是吧?诶那其实很容易的,是不是看到就没有这个记录,那你这时候找这个mean啊,找这个max是不是就没有意义了呀?好这时候我们去执行的时候呢,他会这样说,说no matching啊mean或是max的。哎,就这样一个道理。啊,No match啊呃,那如果我们要这块存在的一个字段,会是什么样的一个效果呢?那你比如这个位置呢,From我们来个limit,哎十吧,哎,我就只看一下这个十条记录啊,我们走起啊这里边呢,我随便呢,我CTRLC一个,咱们这个K1的这个值我就放在这儿了。啊,放在这了啊,那么此时的话呢,我们是不是有这样的一个值了,那有这样的值的一个情况下呢,你看这块是什么呀。
12:05
说select tables optimize,像这呢,就是我们稍微变一变呢,它就有更多丰富的这个叫extra了啊说呢就是查询这个优化以后的这个表啊,优化以后的这个表,哎,我们这实际上就拿这个K1呢,我们去做样的一个来做这样的一个是不是查询啊是吧,来查询,诶查询以后的话呢,我们这个结果呢,找这命就完了啊所以这个呢,其实呃,Meanin呢,也没啥可比的,最后结果呢,是不是就直接就这一条记录就完了。啊,就这个意思啊,就是我们这儿呢,经过这个K1这样的一个过滤以后啊,呃,大家你会发现呢,我们这时候怎么显示的这个,呃,Table,你看这块也是一个闹的这个场景是吧?啊因为这个过滤完以后呢,其实就是单独这条记录了啊,现在也是做了一个优化啊,优化以后呢,这个值,呃就这一条记录呢,那就是它了。啊,就他呢,不存在这个说这个有好多条记录呢,诶是这个,诶针对于他这个过了以后是吧,有很多条记录,这就这一条记录啊,就没有mean和max之说,其实啊。
13:00
好,这块注意一下,我们这个位置呢,哎,我这块稍微标注一下啊它。啊是哎我们,哎是我们这个S1这个表中啊,咱们这个K1字段啊,真实哎存在的这个数据啊。哎,真实,哎存在的这个,诶数据保存一下好,这个呢我们就过了啊,然后呢,再往下看说,当我们的这个查询列表以及搜索条件中只包含属于某一个索引的这个列的时候,也就是说呢,在可以使用覆盖索引的情况下,在里边呢将显示的这个额外信息。什么意思啊,大家你看这啊,就说哎老师你这个呢叫K1等于这个A啊,说我们上面这不也指行了K等A,但你区别呢,是我这块是个星,咱这就不是星了,我是就写了一个叫K1。啊,我们这时候呢,相当于where这块查的是这个K1,然后这块呢,Select的时候也是这个K1,那这时候你看我们情况是什么呀,这叫using index,哎,这个其实是非常棒的哈,嗯,不是using where叫using index使用了这个索引啊,就是我们这个K的这个索引,嗯,这个呢,我们给大家讲一下,它呢,其实就是我们所谓的叫这种覆盖索引啊,前面咱们也提到过这个概念,咱们下一章的时候呢,呃,还会去提这个覆盖索引,就是我们能够用这个覆盖索引的话呢,就建议大家用这个覆盖索引。
14:18
什么叫覆盖索引,大家你看啊,我们现在要查询这个K1,等于这个AK上的话呢,是一个二级索引,那是不是有我们这个K1这个字段所对应的这个叫,诶是不是B加数啊啊,那么这个B加数的话呢,按照我们正常的角度来说,咱们前面也讲过了,你这个二级,所以呢,最后查到的叶子节点以后啊,如果呢,我这块呢,写的是星,是不是要查询这个表中的所有字段啊。那么显然我们这个K1的这个索引当中,哎,这个叶子节点中是不是只存了你这个K1和我们这个主键的值,你要想查询所有的字段,是不是一定要进行这个回表操作吧。对吧,诶一定要回报操作,找我们那个ID构成的那个句数索引,把所有的这个字段呢都找到。哎,但是这个题目当中,你大家你看哈,我们现在查询的话呢,只想查这个K1,而这个K1的话呢,是不是它就存在于我们当前这个K1构成的这个B加数里边,哎,你像我们这个最后的叶子节点K1本身就在这儿了,你要查的还是K1,大家想一下,我们还有没有必要呢,再去做回表操作呀。
15:17
是不是就没有必要了啊,那因为呢,你没有必要再回报操作了,哎,我们把这个呢就称为呢叫哎覆盖索引,所以这个结果呢叫using index啊那既然这样的话呢,有同学可能想说,老师,我们当前这个K1构成的这个B加数,呃,我们叶子节点中除了K1之外呢,咱们是不是还有那个主键ID啊,那我要这样的话呢,你说它是一个覆盖错音吗?哎,大家你想想是不是也是啊,哎,你看我们这个还是叫UC index对吧?啊,也是啊,因为我们叶子节点中,哎就有它这俩字段,但是你要再多一个,这个事儿是不是就变了,我们来一个K2。啊,此时的话呢,你想想我们是不是一定要进行回表了,那既然需要回表,我们就不是一个呃覆盖索引了啊这个呢,就跟我们上面一样啊,这就是个闹了。
16:00
哎,这个大家去再体会一下啊,来体会一下行,这个ID呢,我就留着吧,嗯,再往后这块去说说呢,有些这个搜索条件中虽然出现了这个索引列啊,虽然出现了这个索引链啊,但是却不能够使用到的这个索引。啊,那么哎,这个这个这个等一下再说哈,来大家看这个Y当中,这K呢是大于and k like,哎,你看这有个这个比较恶心的一个情况,来我们首先来执行。说叫using index condition啊,说使用我们这个索引的一个条件啊,其实这个叫条件下推了哈,大家来看一看我们这个呢,执行过程是什么样子的,嗯,这里边呢,明确说了我们使用那叫index k1了啊,使用了这样的一个索引是吧?啊那这个时候的话呢,其实主要针对是这样的一句话啊,K1呢大于这个Z,你看这呢是382,你这样啊我们选中。啊执行你看这块是不是也是382,哎,那说明我们这时候呢,其实考虑的就是呃,针对这个条件,我们使用了这个索引啊呃,那么正常情况下呢,我们这个题目呢,应该怎么去剖析呢?哎,大家注意听啊,正常情况哈情况下的话呢,我们首先呢,针对于K1的这样的一个作用的索引是吧?就它呀,诶咱们在这个B加数当中啊,一层的往下走,然后呢,是不是最后呢,取这个满足啊,这个K1大于Z的这样的一波数据是吧?那么这一波数据呢,底层对应的肯定是很多条了。
17:16
哎,这个就是382条吧,大概是这么多对吧。然后的话呢,我们每一条数据啊,我们说呢,除了你这个K1的值之外,是不是还有对应的一个主见值啊,然后找到每一条数据这个主键值,然后呢,我们去回表,回表呢找我们这个ID的这样的一个句溯索引了是吧?诶然后呢,就层层的往下走,你这儿呢,有好多的ID,然后回过来之后呢,一个一个ID呢,去找到最后的这个叶子节点,诶然后叶子节点当中我们是存储这个表中的真实数据了,哎,有这里边的所有的字段是吧?然后再在这个S字段里边呢,去找满足我们这个K呢,叫like,诶这样的一种形式的。啊,满足我们这个后缀呢,是以A结尾的,呃,你看对应过来哪一个这个K1的这个,诶后缀呢,是满足这个场景的,我们就取出来这个数据。
18:01
哎,就是这样的一个意思,你比如说我们这块呢,查完以后呢,呃,这个满足这个K1大于Z的,这个是有382条记录,那是不是翻回来以后呢,这个呃要找这382条记录,那找完以后的话,有可能只有三条记录满足这个后缀是A的。啊,就是这样一个过程,那么这时候呢,我们这个回表操作啊,其实这个成本呢,还是挺大的,那成本还是挺大的,那整个这个操作的话呢,我们其实可以存在一个优化。啊,就是使用我们这个索引的一个条件是吧?哎,这个优化是一个什么意思呢?就这意思,大家你看这样可不可以啊,我们呢先呢去针对这个K1呢,大于Z,咱不是往下找,一共找了是382条记录,对吧?那么这时候呢,我们字段当中,呃,有你这个K1,然后也有这个主见值对吧?我们先不要着急去回表,我们先来看一看你这个K1当中啊哪些这个后缀呢是哎百分号A啊,就是相当于后缀呢是A的,我们先呢,直接就先过滤找一下你这个382条记录都走一遍,看看谁的这个后缀呢是A。
19:04
那有可能我们找完以后呢,是不是就只有三条记录,然后你再针对这三条记录去做个回表操作,是不是你找那个ID的话呢,最后呢,找了是不是就找那三条记录就行,然后呢,起来给他清一下不就完事了吗。啊,甚至说呢,我们这个时候呢,找完以后呢,发现是个零一条记录也没有,那是不是都不用考虑回表了,那直接呢,是不是就是个空的情况。哎,就是这样子的啊,哎,那么这时候呢,就提到了我们这个叫索引下推啊条件这样的一个概念。啊,咱们找一下这个啊,诶这呢,就我们说的这个,诶,进一步优化以后的这样的一个思路啊,我们说呢,回表操作呢,其实是一个随机IO是比较耗时的,就咱们一开始说的第一种思路啊,先回表后去找我们这个百分号A。那么所以呢,我们上述的这个修改呢,只是改进了一点点,我们是先去2%A再去考虑回表,这样呢就省去了好多回表操作的成本,那我们把这个改进呢,就称为呢索引条件下推。哎,所引条件下推啊,那就这个意思,那就是刚才我说的这样的一个概念啊,大家注意一下这个事儿,那这个呢,显然这个效率呢,是不是要更高一些是吧,就我们说的第二种思路。
20:10
好,接着往下去看,说呢,在这个连接查询啊执行的过程当中,当被驱动的表不能有效的利用索引加快访问速度的时候,MYS呢,一般会为它呢起一个叫哎,Join buffer,内存呢,加快速度,哎,然后呢,也就是我们所说的叫机忆块的一个嵌到循环算法,哎,就这个意思,来,我们走起啊。Select,这是S1,这是S2啊,这个呢,我们叫驱动表啊,这看这啊这叫驱动表,这是叫被驱动表,就我们主要呢是看这个记录里边的,前面这个就是驱动的,后边这个被驱动的,然后呢,On的时候呢,咱们这个common field里边呢,是没有任何的索引的。啊,那没有任何索引的话呢,那就实打实的来了,那我们外边这块呢,是不是整一条记录啊,整一条记录,然后在我们里边这个相当于是这个被清度表这块呢,是不是拿到这个记录,然后我们去做这个匹配是吧,你看外边这块呢,就是100%,然后里边这块呢,跟他呃能够匹配上的啊,我们就大概有10%啊这个呢,我们就是UCV了啊,这就没有字,没有这个索引的这个字段,咱们不是都有这个叫using where嘛。
21:09
对吧,然后后边这个叫using John buffer啊这个呢,就意味着说我们这个呢,也没有任何的索引,那怎么能够帮你去加快一下速度呢?哎,咱们可以考虑呢,诶分配一块独立的内存啊,相当于是一个缓存的空间一样,是吧?诶帮我们呢,去达到一个提速的一个目的啊,也只能这么着了。啊,尽全力了是吧,哎,因为你也不错人嘛。行,就这个意思啊,好在下边说当我们使用这个阻碍连接的时候呢,如果这个Y2子集中包含这个要求被驱动的表的这个诶,某个列等于no的这个值的搜索条件,而且呢,那个列呢又不允许为no啊,这个时候呢叫not exist啊看着挺复杂,其实呢,就是它是跟上边这个一不等于一一样啊,你看这我们查询的时候呢,这是一个Y连接,然后呢,这两个K呢,它得是个相等的啊,这个呢,都是这个有索引的是吧?然后wheres2.id呢,Is now。
22:01
很显然,我们这个S2这个ID呢是个主键,主键呢就不能是no,那你这块让他是no,那是呢,这是呢,就是不存在的吧。哎,它就会多一个叫not exist。Not exists这样的一个意思。OK是吧,诶然后前面这块的话呢,我们这不是,诶这呢算是一个驱动表,这个被驱动表,诶然后在这里边呢,是我们这里边这个被驱动表呢,呃,是这个K1是吧?哎,这个K1的话,它关联的是我们一表里边这个K1啊这个都OK吧。能理解是吧,啊好的啊行,然后的话呢,我们再看下边这个,嗯,这个有点长,咱们就直接的去分析了啊来explain。啊,Select s1,然后where k1呢等于AOK3呢等于A,啊,这块呢,你看他写的叫呃,Using UN。那这个呢,其实就跟我们前面这块提到叫index merge是吧,这块呢是一个O,正常来讲呢,咱们提到说索引呢,只能用一个,当然这块呢,它有索引,它有索引中间是个or,那我们就可以把它俩呢,相当于默置在一起啊,合并一下啊,包括这个位置你看也用了两,那这个呢,也对应的匹配呢,就是叫using unit啊保持呢,我们用了两是吧,哎,就这样是一个合并的一个意思啊。
23:09
诶,所以这块呢,主要就是说的合并,然后下边说呢,我们这个limit呢,咱写的是个零啊,零就没意思了,是不是就你一条记录也不想查看啊,这就是zero limit。啊接limit啊,所以这呢来看它就是一些补充的信息,或者是一些文字的说明啊,不像前面呢,就是一些具体的字段了哈,诶,那我们这块呢,或者前面更像是枚举类型的是吧,完整的一个一个哎,字段值,那我们这儿呢,就是一些描述的信息啊,可能就像是一句话啊。好,然后接下来啊,Explain select from order啊十好,这个呢,我们走一下。啊,大家发现呢,你看这个位置呢,是个闹是吧,说有一些情况下呢,对结果其中的记录啊,进行排序啊,是可以使用到这个索引的。嗯,是可以使用到这个索引的,我们这个时候的话呢,你看这块用到它了。
24:00
呃,然后呢,排序order by它啊这个艾啥玩意没有了是吧,这个确实呢,我们用到K了,因为所以嘛,自然而然就有序是吧。行,那这个没有,那就没啥可说的了啊,这个咱就过了,然后接着往下看。啊,接着往下看啊,诶我们呢,直接呢就在这里边去执行啊,走起啊这里边你看出现了叫using啊主要呢,我们可以跟上边这个做个对比,上边这个我们key呢,本身就是个索引,你是索引的话呢,哎,我们构建索引的时候,其实自然而然的在这个叶子节点来看,是不是本身呢就排序了呀,哎,那你自然而然的是不是就从小到大这块呢?去诶使用就完了啊相当于呢,我们这时候order by你这个字段的话呢,加上一个索引,咱们再讲上一章的时候也提到过是不是,诶是一个优化是吧。诶是一个比较好的一个设置方式啊,Autobi的话呢,就不用你单独再排序了,而这个呢就不一样了啊,我们现在呢,需要呢,诶按照这个字段呢去排序,那你想想我们现实当中啊,或者我们实打实的这个底层的,呃,咱们以这个印度DB来讲,是不是ID文件是吧,这个文件里边呢,没有放着这个呃排按照这个字段排过序的那样的一个必加数。
25:07
那你这时候要排序的话呢,那就比较崩溃了。我们得实打实的是不是进行进行一个,呃,这个把这个表中的数据啊,都加载到这个内存当中,诶我们得给他呢一点点去做这个排序,这叫文件salt啊,这个呢是比较悲壮的。啊,咱们在这个课件里边呢,给大家说一下。嗯,找一找。诶这是吧,好大家看,嗯,咱们这个呢,叫K1啊,这是个no啊,这还好啊,嗯,再往下边说,但是呢,很多情况下呢,排序操作无法使用索引,只能在内存中或者这个磁盘中啊,内存中呢是记录少的时候,磁盘中呢,就是你需要用这个外部这个存储了,是吧?来进行这个排序,那MYSQL呢,把这种在内存中或者磁盘中进行排序的方式呢,统称为呢叫文件排序。那用的叫file,不能够使用上我们现有的这个已经排好序的这个毕加数了,你得先去排,就叫filet,显然呢,这个性能呢,是不是就特别的低下呀,哎,这个呢,是我们尽量要规避的,那如果大家呢,你发现呢,你在执行的时候呢,这叫using file啊,你要考虑一下,是不是我们有必要呢,给这个字段,比如说加个索引是吧,通过这样的方式呢,我们让他提前呢,把这个排好序的这个结构呢,放到我们这个ibd文件里边。
26:23
啊,然后呢,生成这个文件的时候呢,呃,这个生成这个被加数的时候呢,花一定时间,但是呢,你后期呃,再去查询的时候呢,这个性能就上来了。对吧,哎就能够,哎,你这可能就直接呢,从一个慢查询就跨步到这个非慢查询里边了。啊,应该能听懂啊,好,再往下看啊,这个文字也很多啊,我们直接呢就上来就跑了,说呢这个啊,这个select distinct。啊,这个呢,是一个这个驱虫了啊,哎,Common from SE这个呢,针对我们是一个普通的字段啊,我们想强调的点呢,叫using temporary。啊,这个呢,就是使用这个临时表的意思。
27:01
啊,使用临时表的,也就是说啊,呃,我们现在呢,想去重,那你是不是也得把这个呢,先加载到内存当中,然后呢,比较一下哪些是一样的,哪些是不一样的,咱们前面讲那个union的时候呢,是不是也提到了它叫using temporary是吧。所以这里边凡是呢,我们发现呢,包含有像这个distinct啊,还有这个UN啊,这样的这个场景当中,如果呢,你不能够有效的利用索引来完成这个。哎,操作的话呢,那这时候我们就需要有一个叫using temporary。啊,那同样的来我们CTRLC一下,大家你看啊,我们这时候呢,把它粘过来,我改成了叫这个K1吧。哎,那此时呢,我们再去选中呢,做一个执行,你看就不一样啊,因为这个位置呢,它本身呢,是不是已经是一个有序的状态了,我们驱虫起来就要很简单,而这个的话呢,本身呃,它是无序的状态啊,你得先有个临时表,然后再去比较这个驱虫这个场景。啊,这个大家要小心一点,那下边这个呢,一样的道理啊,我们group by的时候呢,按照这个字段呢,进行一个分组是吧,那你分组的话呢,这个字段本身呢,也没有个呃,提前的索引对应的B加数的一个支撑,那你就得需要呢,用一个临时表的方式了。
28:10
啊,内部的临时表是吧,那这个道理啊。好,然后呢,我们再看这个后边这个,呃,Explain select k啊,直接我们选中了去执行啊,那这是我们group呢,这个是不是一个索引啊,啊,那是个索引呢,它就不一样了啊,这叫using index。啊,Using index,好,所以说呢,我们在计划执行计划当中,如果出现了叫using temporary的话呢,它并不是一个好的征兆。啊,那么因为建立与维护临时表呢,需要付出很大的这个成本,所以呢最好呢能够使用,所以呢来去替代我们使用这个临时表的方式,诶大家呢,可以这样呢做一个借鉴啊好,那么至此的话呢,咱们就把这个X呢讲完了,然后呢,整个呢,关于explain呢中的这些字段呢,咱们就也告一段落,哎那么后续的话呢,大家哎关于这个慢查询的这个语句,我们重点的话呢,就使用explain呢去进行一个解释啊最后呢有个小结简单看一下说exce的话呢,它不考虑各种各样的这个catch。
29:06
啊,就是你有没有缓存我不管啊,你是从这个缓存中啊,还是从这个磁盘中去加载,我不管,我主要呢,就是看我们当前这个circle靠不靠谱。那个也就是说呢,我们考虑你是从哪加载的,这是另外的优化策略啊,不参与我们这个SQL语句本身。第二的话呢,叫explain,不能够显示MY在执行查询时呢,所做的这个优化工作啊,这个咱们只能看到它,这个相当于结论呢,是选哪个了,这块有三个这个索引是吧,我们就选了这个了啊这个中间他怎么选的这个我们看不到了。这个呢,说不会告诉你关于触发器存储过程的信息,或者呢,用户自定义的函数对查询的一个影响的过程啊,这个我们是看不到的,直接呢,呈现给我们的就是他最终呢选择的这种方案啊,那部分统计的信息呢,是估算的,也并非精确的这个值。啊,这个呢,也很好去理解,包括我们说Rose就大概是吧,这样的一个范围啊,大概这样的一个比例而已,啊行,那这块呢,大家下来呢,重点要要看的就是这个plan啊。
我来说两句