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有热点数据也会被挤掉
那么热点数据会受影响
解决方法:创建临时表,将需要满足条件的行从被驱动表选出来。用临时表作为被驱动表