博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
left join 要点
阅读量:4082 次
发布时间:2019-05-25

本文共 1586 字,大约阅读时间需要 5 分钟。

总的来说,left join的性能优化(尤其还涉及到排序)是个比较复杂、系统的问题,涉及到

驱动表

索引

的内在实现,仅能在以下三的有所关注:

1. 连接字段编码一致      悲剧:https://www.cnblogs.com/jarjune/articles/7912722.html

2. 认清主表作相应的优化,比如索引、排序之类的

3. 尽量用inner join

MySQL内部采用了一种叫做 nested loop join的算法。Nested Loop Join 实际上就是通过驱动表的结果集作为循环基础数据,然后一条一条的通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果

那么为什么一般情况下join的效率要高于left join很多?一般情况下参与联合查询的两张表都会一大一小,如果是join,在没有其他过滤条件的情况下MySQL会选择小表作为驱动表,但是left join一般用作大表去join小表,而left join本身的特性决定了MySQL会用大表去做驱动表,这样下来效率就差了不少

我验证了一下

no index

user_id index

了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表

http://blog.csdn.net/dc2222333/article/details/78234649

left join不变,干嘛要根据非驱动表的字段排序呢?我们前面说过“对驱动表可以直接排序对非驱动表(的字段排序)需要对循环查询的合并结果(临时表)进行排序!”的。

MySQL中LEFT JOIN的主表

http://ourmysql.com/archives/775

EXPLAIN SELECT *

FROM posts
LEFT JOIN categories ON posts.category_id = categories.id
WHERE categories.id = ‘一个已经存在的ID’
ORDER BY posts.created DESC

结果如下所示:

table      key         Extra

categories PRIMARY     Using filesort
posts      category_id Using where

在explain的结果中,第一行表示的表就是主表,所以说在此查询里categories是主表,而在我们的经验里,LEFT JOIN查询里,左表(posts表)才应该是主表,这产生一个根本的矛盾,MySQL之所以这样处理,是因为在我们的WHERE部分,查询条件是按照categories表的字段来进行筛选的,而恰恰categories表存在合适的索引,所以在查询时把categories表作为主表更有利于缩小结果集

那explain结果中的Using filesort又是为什么呢?这是因为主表是categories表,从表是posts表,而我们使用从表的字段去ORDER BY,这通常不是一个好选择,最好改成主表字段,如果鉴于需求所限,无法改成主表的字段,那么可以尝试添加如下索引

ALTER TABLE `posts` ADD INDEX ( `category_id` , `created` );

再运行SQL时就不会有Using filesort了,这是因为主表categories在通过category_id连接从表posts时,可以进而通过索引直接得到排序后的posts结果。(这个我没验证出来)

主观上一旦搞错了主表,可能怎么调整索引都得不到高效的SQL,所以在写SQL时,比如说在写LEFT JOIN查询时,如果希望左表是主表,那么就要保证在WHERE语句里的查询条件尽可能多的使用左表字段,进而,一旦确定了主表,也最好只通过主表字段去ORDER BY。

你可能感兴趣的文章
C++ STL标准库 算法
查看>>
JVM内存模型_Minor GC笔记
查看>>
SpringCloud学习之PassCloud——(一)PassCloud源代码下载
查看>>
Linux下安装Python环境并部署NLP项目
查看>>
Nginx篇-springCloud配置Gateway+Nginx进行反向代理和负载均衡
查看>>
Nginx篇-Nginx配置动静分离
查看>>
缓存篇-Redis缓存失效以及解决方案
查看>>
缓存篇-使用Redis进行分布式锁应用
查看>>
缓存篇-Redisson的使用
查看>>
phpquery抓取网站内容简单介绍
查看>>
找工作准备的方向(4月22日写的)
查看>>
关于fwrite写入文件后打开查看是乱码的问题
查看>>
用结构体指针前必须要用malloc,不然会出现段错误
查看>>
Linux系统中的美
查看>>
一些实战项目(linux应用层编程,多线程编程,网络编程)
查看>>
我觉得专注于去学东西就好了,与世无争。
查看>>
原来k8s docker是用go语言写的,和现在所讲的go是一个东西!
查看>>
STM32CubeMX 真的不要太好用
查看>>
STM32CubeMX介绍、下载与安装
查看>>
电机和桨叶要搭配选择
查看>>