连接查询和分步查询详细分析
First
mysql实战45讲读书笔记
Join连接查询
首先建一个表:
连接查询的流程:
从《高性能mysql》截取
很明显的看出来:连接查询就是先从驱动表查出所有满足条件的数据,然后再把驱动表的数据作为条件,一条一条的查询被驱动表。
本质上来说,mysql会将所有的查询都以类似的方式运行。例如:在from子句后面有子查询,会先执行子查询的语句,将结果放入内存临时表中,将这个表当成一个普通的表看待,注意:临时表是没有任何的索引的!(mysql 5.6之前)
mysql在生成执行计划时,并不是按照我们定义的顺序进行的,而是预估需要读取的数据页的数量,来评估使用何种执行计划。
如果被驱动表没有可用的索引时,mysql执行的时 Block Nested-loop join。详细执行过程:
- 查询出驱动表的所有满足条件的数据,读入线程内存 join_buffer中
- 扫描被驱动表,取出每一行数据,和join_buffer中的数据进行比较,满足join 条件的,作为结果集的一部分返回。
优化建议:
连接查询时,确保On子句或者using子句的列一定要有索引。
分步查询:
分步查询就是将一个连接查询拆分成多个独立的单表查询,在后端自行关联。
mybatis通过resultMap中的association选项进行分布查询。
分步查询相对于连接查询的优势:
- 分步查询便于拓展:便于水平切分
- 执行单个查询,可以减少锁的竞争
- 可以减少冗余数据的查询,比如:如果连接索引没有索引,并且join_buffer大小不足以装下驱动表的数据,那么就会分段的关联,这时候就会多次对被驱动表全表扫描
当然,分布查询因为是多次查询数据库,那么网络io这一点可能会较连接查询高。
后续会对两种方式进行测试。
下一篇:
mysql数据库密码的修改