老男孩Linux运维MySQL中级DBA-第12章-MySQL驱动表和被驱动表说明-补
# 驱动表和被驱动表
#### 1.什么是驱动表和被驱动表?
在join连接查询中,驱动表在SQL语句执行的过程中总是先被读取。而被驱动表在SQL语句执行的过程中总是后被读取。在驱动表数据读取后,放入到join_buffer后,再去读取被驱动表中的数据来和驱动表中的数据进行匹配。如果匹配上则作为结果集返回,否则丢弃。
#### 2.学习驱动表和被驱动表有什么用?
在mysql的join连接语句优化中有用。
#### **3.如何区分驱动表和被驱动表**
(一)对于已有SQL语句,可使用explain查看SQL语句执行计划。
在输出的执行计划中,排在第一行的表是驱动表,排在第二行的表是被驱动表。
(二)join连接,根据连接类型确定哪个表是驱动表,哪个表是被驱动表:
没where条件时:
1.当使用left join时,左表是驱动表,右表是被驱动表
2.当使用right join时,右表是驱动表,左表是被驱动表
3.当使用join时,mysql会选择数据量**比较小的表作为驱动表**,大表作为被驱动表
https://blog.csdn.net/qq_20891495/article/details/93744495
**这里对于大小的判断,是指真正参与关联查询的数据量所占用的****join_buffer****的大小来区分的,而不是根据表中所有的数据行数来判断的。
有where条件时:
带where条件的是驱动表,否则是被驱动表
(三)优化器判断(可能不准,需要强制left指定)
mysql> desc select * from city join country on city.countrycode=country.code where city.population<100000 and country.SurfaceArea>10000000;
(四) 人为判断(结果集小的作为驱动表)
1.mysql>select count(*) from country where country.SurfaceArea>10000000; +----------+ | count(*) | +----------+ | 2 | +----------+ mysql>select count(*) from city where city.population<100000 ; +----------+ | count(*) | +----------+ | 517 | +----------+
补充: 如果where后的列中都有索引,会选择结果集小的作为驱动表.
#### 4.如何优化join语句查询
1)多表连接时,用小表驱动大表,驱动表创建索引时,mysql可能用不到。
2)在大表(被驱动表)上建立索引。
3)优化器会自动判断查询语句中的谁做为驱动表更合适.有可能会出现选择错误。
4)可以通过left join强制驱动表和被驱动表,从而干预执行计划。
5)多表联接并且有排序时,排序字段必须是驱动表里的,否则排序列无法用到索引;