mysqljoin⼩表驱动⼤表_了解MySQL联表查询中的驱动表,优
化查询,以⼩表驱动⼤表...
⼀、为什么要⽤⼩表驱动⼤表
1、驱动表的定义
当进⾏多表连接查询时, [驱动表] 的定义为:
1)指定了联接条件时,满⾜查询条件的记录⾏数少的表为[驱动表]
2)未指定联接条件时,⾏数少的表为[驱动表](Important!)
忠告:如果你搞不清楚该让谁做驱动表、谁 join 谁,请让 MySQL 运⾏时⾃⾏判断
既然“未指定联接条件时,⾏数少的表为[驱动表]”了,⽽且你也对⾃⼰写出的复杂的 Nested Loop Join 不太有把握(如下⾯的实例所⽰),就别指定谁 left/right join 谁了,请交给 MySQL优化器 运⾏时决定吧。
如果您对⾃⼰特别有信⼼
2、mysql关联查询的概念:
MySQL 表关联的算法是 Nest Loop Join,是通过驱动表的结果集作为循环基础数据,然后⼀条⼀条地通过该结果集中的数据作为过滤条件到下⼀个表中查询数据,然后合并结果。
例: user表10000条数据,class表20条数据
select * from user u left join class c u.userid=c.userid
这样则需要⽤user表循环10000次才能查询出来,⽽如果⽤class表驱动user表则只需要循环20次就能查询出来
例:
select * from class c left join user u c.userid=u.userid
⼩结果集驱动⼤结果集
以此保证:永远⽤⼩结果集驱动⼤结果集(Important)!
⼆、优化联表查询
优化第⼀步之:根据驱动表的字段排序
left join不变,⼲嘛要根据⾮驱动表的字段排序呢?我们前⾯说过“对驱动表可以直接排序,对⾮驱动表(的字段排序)需要对循环查询的合并结果(临时表)进⾏排序!”的。
explainSELECTmb.id……FROM mb LEFT JOIN mbei ON mb.id=mbei.mb_id INNER JOINu ON mb.uid=u.uidWHERE 1=1
ORDER BY mb.id DESClimit0,10
也满⾜业务场景,做到了rows最⼩:
优化第⼆步:去除所有JOIN,让MySQL⾃⾏决定,explain第⼀张表就是驱动表,数据量⽐其它两张表都要⼩!
explainSELECTmb.id……FROMmb,mbei,uWHEREmb.id=mbei.mb_idand mb.uid=u.user_id
order by mbei.apply_time desclimit0,10
⽴竿见影,驱动表⼀样是⼩表 mbei:
id select_type table type possible_keys keykey_len ref rows Extra1 SIMPLE mbei ALL mb_id (NULL) (NULL) (NULL)
13388Using filesort1 SIMPLE mb eq_ref PRIMARY,userid PRIMARY 4 mbei.mb_id 1
1 SIMPLE u eq_ref PRIMARY PRIMARY 4 mb.uid 1 Using index
三、总结
1、不要过于相信你的运⽓!
2、不要相信你的开发环境⾥SQL的执⾏速度!
3、请拿起 explain 武器,如果你看到以下现象,请优化:
1)出现了Using temporary
2)rows过多,或者⼏乎是全表的记录数
3)key 是 (NULL)
4)possible_keys 出现过多(待选)索引
>sql left join 多表连接

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。