我们DBA不让使用join, 使用join有什么问题呢?
2. 如果有两个大小不同的表做join, 应该用哪个表做驱动表呢?
1 Index Nested-Loop Join
select * from t1 straight_join t2 on (t1.a=t2.a);
被驱动表t2的字段a上有索引, join过程用上了这个索引, 因此这个语句的执行流程是这样的:
1. 从表t1中读入一行数据 R;
2. 从数据行R中, 取出a字段到表t2里去查找;
3. 取出表t2中满足条件的行, 跟R组成一行, 作为结果集的一部分;
4. 重复执行步骤1到3, 直到表t1的末尾循环结束
两个结论:
1. 使用join语句, 性能比强行拆成多个单表执行SQL语句的性能要好;
2. 如果使用join语句的话, 需要让小表做驱动表。
2 Simple Nested-Loop Join
select * from t1 straight_join t2 on (t1.a=t2.b);由于表t2的字段b上没有索引, 因此再用图2的执行流程时, 每次到t2去匹配的时候, 就要做一次全表扫描
MySQL也没有使用这个Simple Nested-Loop Join算法, 而是使用了另一个叫作“BlockNested-Loop Join”的算法, 简称BNL。
3 Block Nested-Loop Join
被驱动表上没有可用的索引, 算法的流程是这样的:
1. 把表t1的数据读入线程内存join_buffer中, 由于我们这个语句中写的是select , 因此是把整个表t1放入了内存;
2. 扫描表t2, 把表t2中的每一行取出来, *跟join_buffer中的数据做对比, 满足join条件的, 作为结果集的一部分返回
4 小结
如果可以使用被驱动表的索引, join语句还是有其优势的;
2. 不能使用被驱动表的索引, 只能使用Block Nested-Loop Join算法, 这样的语句就尽量不要使用;
3. 在使用join的时候, 应该让小表做驱动表 (a join b 就是 a是驱动表)
