首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >MySQL多表关联查询优化

MySQL多表关联查询优化

作者头像
全栈程序员站长
发布2022-09-02 10:42:26
发布2022-09-02 10:42:26
3.7K0
举报

大家好,又见面了,我是你们的朋友全栈君。

背景

最近在对运营报表导出进行优化,总结了一些多表关联查询优化的点记录一下。

避免临时表

通过 Explain 分析 SQL 语句,尽量不要使用到临时表。GROUP BY (Explain具体详解,可以看这篇博客

最容易造成使用临时表,GROUP BY 与临时表的关系 :   1. 如果GROUP BY 的列没有索引,产生临时表.   2. 如果GROUP BY时,SELECT的列不止GROUP BY列一个,并且GROUP BY的列不是主键 ,产生临时表.   3. 如果GROUP BY的列有索引,ORDER BY的列没索引.产生临时表.   4. 如果GROUP BY的列和ORDER BY的列不一样,即使都有索引也会产生临时表.   5. 如果GROUP BY或ORDER BY的列不是来自JOIN语句第一个表.会产生临时表.   6. 如果DISTINCT 和 ORDER BY的列没有索引,产生临时表. 如果业务需求没法更改,也不需要强制去掉临时表。

缩小数据范围

接下来进行优化第二步,将临时表缩小到最小范围。SQL 执行过程大体如下:

  1. 执行FROM语句
  2. 执行ON过滤
  3. 添加外部行
  4. 执行where条件过滤
  5. 执行group by分组语句
  6. 执行having
  7. select列表
  8. 执行distinct去重复数据
  9. 执行order by字句
  10. 执行limit字句

当两个表进行Join操作时,主表的Where限制可以写在最后,但从表分区限制条件不要写在Where条件中,建议写在ON条件或者子查询中。主表的分区限制条件可以写在Where条件中(最好先用子查询过滤)。示例如下:

代码语言:javascript
复制
select * from A join (select * from B where dt=20150301)B on B.id=A.id where A.dt=20150301; 
select * from A join B on B.id=A.id where B.dt=20150301; --不允许 
select * from (select * from A where dt=20150301)A join (select * from B where dt=20150301)B on B.id=A.id;

第二个语句会先Join,后进行分区裁剪,数据量变大,性能下降。在实际使用过程中,应该尽量避免第二种用法。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/138924.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年5月3,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 避免临时表
  • 缩小数据范围
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档