视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
MySQL调优----LEFTJOIN_MySQL
2020-11-09 19:46:55 责编:小采
文档
 前情提要 : 需求就是一个普通的两个表连接从而查询出详细信息。其中A表是大表, 测试数据都有数万条; B表是小表大概1000多条数据。

1. 为了赶工写出的未优化SQL(为突出主题, 返回字段用 * 代替不写出详细字段, WHERE条件也去掉了):

SELECT 
 	 *
 FROM
 A a 	
 LEFT JOIN
 	B b 
 ON 
 	 a.JOB_ID = b.ID

耗时:3.712s



rows字段代表这个步骤相对上一步结果每一行需要扫描的行数,可以看到这个sql需要扫描的行数为22711*1230, 这几乎是两个表做笛卡尔积的开销了(select * from a, b)。

MySQL对JOIN的处理采用了一种叫做BLOCK Nested-Loop 的算法。 Block Nested-Loop 算法是通过驱动表(可以简单理解为前面的表)的结果集作为循环基础数据, 然后一条一条的通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。 如果还有第三个参与 JOIN, 则再通过前面两个表的 JOIN 结果集作为JOIN的基础数据,再一次通过循环查询条件到第三个表中查询数据。 结论: 驱动表(前面表)的数据量决定了总扫描数。

2. 从业务上

都是全表扫描, 然后我发现左表数据在业务上如果右表为NULL就没意义了, 然后改为INNER JOIN。

耗时: 2.745s

3. 可以看到上面的type都是ALL

system/const/eq_ref/ref/range/index/ALL ---- 从左到右效率递减

都是type都是ALL考虑到连接的条件是否可以为主键, 有主键的话MySQL可以使用索引查询, 效率会提升很多。

由于A表是历史表做链接的字段不是主键, 所以只能在B表把这个字段加上主键。

耗时: 2.672s

还是很慢, 因为还没建立索引, 现在对B表ID字段加上索引, 结果如下:

耗时:0.109s

下载本文
显示全文
专题