Join使用的是Nested-Loop Join算法,Nested-Loop Join有三种

select * from t1 join t2 on t1.a = t2.a;-- a 100条数据, b 1000条数据

每次在t2中做全表查询时,全表扫描可就不保证在内存里了,Buffer Pool会淘汰,有可能在磁盘。

Block Nested-Loop Join(MYSQL驱动链接没有使用索引)

会遍历t1全表,将t1数据加载到join_buffer中,再遍历t2全表,让t2的每条数据去匹配join_buffer中t1缓存的数据。

t1全表扫描 = 100次

t2全表扫描 = 1000次

查询次数 = 1100次

join_buffer中比较 = 100 * 1000次

比较的次数和Simple Nested-Loop Join是一样的,但是比较的过程会比Simple Nested-Loop Join快很多,性能更好。

join_buffer是有大小的,如果t1查出来的数据是大于join_buffer大小的,则会先加载部分t1中的数据,比较完t2以后,清空join_buffer,再加载t1中剩余数据,加载不完全,再重复该操作。

t1全表扫描次数和join_buffer中比较1次数不变,但是t2的扫描次数会根据分段次数做一个乘法。

假设,驱动表的数据行数是 N,需要分 K 段才能完成算法流程,被驱动表的数据行数是 M。

K = λ * N

扫描被驱动表次数 = M * λ * N

λ是和join_buffer的大小有关的,join_buffer大小足够的情况下,大表驱动和小表驱动的时间是一样的。

需要分段的情况下,分段次数越少,被驱动表扫描的次数也会越少,所以应该采用小表驱动。

Index Nested-Loop Join(MYSQL驱动链接使用索引)

还是以上面的sql为例,如果a字段是有索引的。

t1表会扫描全表,t1表中每条数据会去t2表中做索引查询,查到id后再进行回表查询(如果连接字段是t2表的主键,回表操作将省略)。

t1扫描全表 = 100次

t2索引查询 = log1000次

t2回表查询 = log1000次

假设,驱动表的数据行数是 N,被驱动表的数据行数是 M。

总查询次数 = N + N * 2logM

由上可见,驱动表数据越大,查询的次数会越多,所以应该使用小表作为驱动表。

文章参考《MySQL实战45讲--第34讲》

总结

更多相关文章

  1. IM-A820L限制GSM,WCDMA上网的原理(其他泛泰机型可参考)7.13
  2. Android下Excel的操作
  3. 【Android】文件读写操作(含SDCard的读写)
  4. android 百度地图3.0+常用操作
  5. 转:Android下文件操作模式(含SDCard的读写)
  6. android音频、视频、拍照基础操作
  7. Android之再谈文件操作和SDcard读写
  8. android的文件操作。(未整理完成)
  9. Android中Activity之间访问互传参数

随机推荐

  1. android设备连接到pc进行应用程序调试
  2. 使用Kotlin开发android学习记录(一)
  3. Android 游戏开发的一些基础和个人经验
  4. Android - 图解向 Android Studio 中导入
  5. android Glide简单使用
  6. 在Android平台上实现条型码扫描与识别
  7. Android2.3发布
  8. Android 布局之LinearLayout和RelativeLa
  9. Android 2.2新增Widget之ProtipWidget源
  10. Android启动脚本init.rc