AI智能
改变未来

Mysql – join 优化

MMR解决的不是join优化,而是回表优化:

  mutil-range read ,正如他的名字一样,优化的是离散范围的读,具体是优化在主键上离散范围的读

  如果是从辅助索引读取符合条件的 (索引列的值 +主键列的值),是需要根据主键列的值去读主键索引的行记录的,但是如果从辅助索引得到的主键索引是不连续的比如

  辅助索引是 (A, 1) (A1, 100) (A2, 1000)

  因为回表是一行行回的,所以就会产生离散读取主键索引的情况

  MMR做的事情是把得到的主键先放在 read_rnd_buffer ,然后排序,然后再去主键索引读取数据行,这样的话就能减少离散读

BKA依赖于 MMR进行join优化:

  Batch Key Access ,正和她的名字一样,是批量的用一堆主键去读取主键索引。

  在被驱动表有主键的情况下,驱动表读一行就要去被驱动表通过主键在B+树查找一次,如果可以一次性给许多主键,并且是有序的话,就能大大提高效率

  BKA用上了 NLJ(indexnestedloopjoin)情况下用不上的joinbuffer,每读一行驱动表,就将连接字段放入joinbuffer

 然后将joinbuffer传给 MMR ,MMR负责去连接字段对应的被驱动表的辅助索引上读取主键,并且放到read_rnd_buffer ,然后排序,再去被驱动表的主键索引读取行数据

大表join对内存的影响:

 如果被驱动表是大表,驱动表也比较大,能被分成几个joinbuffer,那么被驱动表这张大表将被扫描多次

  Buffer Pool的内存页的缓存机制是前 8/5 是young区域,后 8/3是old区域,内存页 LRU淘汰机制下,新读入的内存页不会马上到young区的头部,因为不能保证这个内存页确实是热数据

 所以只能把他放到old的头,如果被驱动表是大表,8/3放得下的话没问题,但是如果放不下,则会挤掉young区,如果young有热点数据也会被挤掉

 那么热点数据会受影响

  

 解决方法:创建临时表,将需要满足条件的行从被驱动表选出来。用临时表作为被驱动表

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » Mysql – join 优化