首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mysql - join 优化

Mysql - join 优化

作者头像
执生
发布2020-12-02 15:43:13
6410
发布2020-12-02 15:43:13
举报
文章被收录于专栏:立权的博客立权的博客

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

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

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

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

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

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

BKA 依赖于 MMR 进行 join 优化:

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

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

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

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

大表 join 对内存的影响:

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

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

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

  那么热点数据会受影响

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-11-30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档