34 join优化

对性能影响比较大的是SQL的扫描行数和与MYSQL交互次数

NLJ过程

被驱动表的索引可以被用上

select * from t1 straight_join t2 on (t1.a=t2.a);

t1和t2表a字段都有索引,执行过程如下,这里的扫描指的是引擎从磁盘读取记录数据

1.从t1表读取一行(执行器调用引擎接口?),扫描了一行
2.取出这行的a字段,到t2表树搜索取出t2符合条件的行(执行器调用引擎接口?)跟t1读的行组成一行,作为结果集的一部分,扫描了一行
3.重复上面的过程直到t1读完

BLJ流程

被驱动表上没有可用的索引的情况下会使用

select * from t1 straight_join t2 on (t1.a=t2.b);

t2表b字段没有索引,执行顺序如下
扫描表 t1,顺序读取数据行放入 join_buffer 中,放到 join_buffer 满,(执行器调用引擎?)继续第 2 步;
扫描表 t2,把 t2 中的每一行取出来,跟 join_buffer 中的数据做对比,满足 join 条件的,作为结果集的一部分返回(执行器调用引擎?);
清空 join_buffer;继续扫描表 t1,顺序读取放入 join_buffer 中,继续执行第 2 步。

BNL和SNL从时间复杂度上看是一样的,但是BNL都是内存判断操作,性能更好。SLJ模式和引擎交互次数多,得多次从磁盘读取数据,而BNJ模式只需要读取一次。速度快上很多,性能也好。

BNL的join_buffer放不下了,就分段放
BNL也应该让小表做驱动表,减少扫描行数。

问题

1.扫描行和扫描索引有什么不同
2.什么是驱动表和被驱动表?
驱动表是主动发起查询的表,被驱动表是根据on条件被动查询的表
3.straight_join的使用场景?
用于内连接,即返回两个表的交集部分。强制使用左边的表作为被驱动表。而left join和right join已经确定了驱动表。
4.单表使用二级索引范围查询,执行器和引擎交互的次数是多少次 ?比如select * from t1 where a > 2 and a < 100,a是二级索引?单表使用二级索引查询的过程是什么样子的
5.mysql搜索一棵树的时间复杂度是多少?
每次搜索一棵树近似复杂度是以 2 为底的 N的对数。所有的节点都在磁盘里,读盘的次数是树的层高。数据读出来是有序的,有序数组用二分法做搜索时间复杂度是log2N。
6. 使用join的前提是用上索引。举的反面例子是把join拆成循环里面使用SQL查询(多次网络IO代价高),如果拆成的语句使用的是in范围查询用得上索引并且只需要一次网络IO,差别还有那么大吗?个人感觉没有。
7. 可以使用join语句吗?怎么使用
如果可以用上被驱动表的索引,可以走树搜索找到对应的行(总比全表扫描强),是可以使用的。比最傻的循环里SQL查询,多次网络IO好。小表当驱动表,驱动表的大小对扫描行数的影响更大。
8.BNL怎么优化?
下面的措施都是减少扫描行数的。
(1)小表当驱动表。
(2)增大join_buffer
9.如何判断要不要使用join?
如果explain的结果里Extra字段为BNL则不要使用
10.什么是小表?
在决定哪个表做驱动表的时候,应该是两个表按照各自的条件过滤,过滤完成之后,计算参与 join 的各个字段的总数据量,数据量小的那个表,就是“小表”,应该作为驱动表。
11.请求响应慢有什么影响?
大部分请求会阻塞

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值