广告
返回顶部
首页 > 资讯 > 数据库 >MySQL之join查询优化方式
  • 699
分享到

MySQL之join查询优化方式

MySQL join查询join查询优化MySQL查询优化 2023-03-12 17:03:26 699人浏览 独家记忆
摘要

目录Mysql join查询优化1. 那什么是驱动表呢?2. 复杂的sql怎么识别驱动表呢?3. 关联查询原理是怎样的?4. 该如如何优化?5. 实例mysql优化(关联查询优化)准

MySQL join查询优化

在日常的开发中,我们经常遇到这样情况:select * from TableA  inner join TableB...它响应速度一直很快的,随着数据的增长,突然有一天开始很慢了。那该怎么破?

对,驱动表是突破口,

1. 那什么是驱动表呢?

  • 指定了联接条件时,满足查询条件的记录行数少的表为驱动表
  • 未指定联接条件时,行数少的表为驱动表(Important!)

如果你搞不清楚该让谁做驱动表、谁 join 谁,就别指定谁 left/right join 谁了,请交给 MySQL优化器 运行时决定吧。

2. 复杂的sql怎么识别驱动表呢?

按经验谈,使用EXPLaiN, 第一行出现的表就是驱动表。

3. 关联查询原理是怎样的?

MySQL 表关联的算法是 Nest Loop Join,是通过驱动表的结果集作为循环基础数据,然后一条一条地通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。

//例: user表10000条数据,class表20条数据
select * from user u left join class c u.userid=c.userid

上面sql的后果就是需要用user表循环10000次才能查询出来,而如果用class表驱动user表则只需要循环20次就能查询出来。

4. 该如如何优化?

优化的目标是尽可能减少JOIN中Nested Loop的循环次数,以此保证:永远用小结果集驱动大结果集。

排序的字段也有影响,有条原则:对驱动表可以直接排序,对非驱动表(的字段排序)需要对循环查询的合并结果(临时表)进行排序!

5. 实例

explain select * from user u left join class c on u.userid=c.userid INNER JOIN subject s on c.subjectId=s.id 
 WHERE 1=1 ORDER BY u.create_time DESC limit 0,10

够复杂吧。假如,user表有千万级记录,class表要少得多,从执行计划的得知驱动表(数据到千万级)。由于动用了“LEFT JOIN”,所以相当于已经指定了驱动表。

如何优化?

//优化第一步:LEFT JOIN改为JOIN,对,直接 join!
explain select * from user u join class c on u.userid=c.userid INNER JOIN subject s on c.subjectId=s.id 
 WHERE 1=1 ORDER BY u.create_time DESC limit 0,10
//优化第二步:从上面执行计划得知, 有Using temporary(临时表);Using filesort,解决方法是调整排序字段(借助前面讲过排序的原则)
explain select * from user u join class c on u.userid=c.userid INNER JOIN subject s on c.subjectId=s.id 
 WHERE 1=1 ORDER BY c.id DESC limit 0,10

总之,sql优化中explain工具是非常重要的武器。

MySQL优化(关联查询优化)

准备数据

#分类
CREATE TABLE IF NOT EXISTS `class` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`card` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
);
#图书
CREATE TABLE IF NOT EXISTS `book` (
`bookid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`card` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`bookid`)
);
 
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
 
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));

left join左外连接

看这个分析结果发现:在 class 表上添加的索引起的作用不大。

结论: 

- **小表驱动大表**

  • - 小表:相对来说记录较少的表
  • - 大表:相对来说记录较多的表

- 驱动方式识别

  • left join:左边驱动右边(此时把小表放在左边)
  • right join:右边驱动左边(此时把小表放在右边)

- 加索引的方式:通常建议在大表(被驱动)的表加索引,效率提升更明显。

- 原因:

  • 原因1:被驱动表加了索引之后,收益更大。从 ALL -> ref
  • 原因2:外连接首先读取驱动表的全部数据,被驱动只读取满足连接条件的数据。

inner join:MySQL会自动根据表中的数据选择驱动表

小结:

- 保证被驱动表的 join 字段被索引。join 字段就是作为连接条件的字段。

- left join 时,选择小表作为驱动表(放左边),大表作为被驱动表(放右边)

- inner join 时,mysql 会自动将小结果集的表选为驱动表。

- 子查询尽量不要放在被驱动表,衍生表建不了索引

- 能够直接多表关联的尽量直接关联,不用子查询

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

您可能感兴趣的文档:

--结束END--

本文标题: MySQL之join查询优化方式

本文链接: https://www.lsjlt.com/news/199459.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL之join查询优化方式
    目录MySQL join查询优化1. 那什么是驱动表呢?2. 复杂的sql怎么识别驱动表呢?3. 关联查询原理是怎样的?4. 该如如何优化?5. 实例MySQL优化(关联查询优化)准...
    99+
    2023-03-12
    MySQL join查询 join查询优化 MySQL查询优化
  • MySQL之join查询如何优化
    这篇文章主要介绍“MySQL之join查询如何优化”,在日常操作中,相信很多人在MySQL之join查询如何优化问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MySQL之join查询如何优化”的疑惑有所帮助!...
    99+
    2023-07-05
  • Mysql查询优化之IN子查询优化方法详解
    目录物化表物化表转连接总结物化表 首先提出一个不相关的IN子查询 SELECT * FROM s1 WHERE key1 IN (SELECT commo...
    99+
    2023-02-09
    mysql in子查询优化 mysql in语句优化 mysql查询效率优化
  • MySQL查询优化的方式
    本篇内容介绍了“MySQL查询优化的方式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 在分析查询性能时...
    99+
    2022-10-18
  • 详解Mysql两表 join 查询方式
    目录一、SQL基本语法格式二、3种join方式1. left join(左连接)2. right join(右连接)3. inner join(内连接)4. 在理解上面的三种join下,查询(A -  A&ca...
    99+
    2022-10-23
  • 详解Mysql两表 join 查询方式
    目录一、SQL基本语法格式二、3种join方式1. left join(左连接)2. right join(右连接)3. inner join(内连接)4. 在理解上面的三种join...
    99+
    2022-11-13
    Mysql join 查询方式 Mysql join 查询
  • mysql的join查询和多次查询方式比较
    目录join查询和多次查询比较查询语句join、on、where执行顺序一、典型SELECT语句完整的执行顺序二、from三、on四、on 条件与where 条件五、join 流程总结join...
    99+
    2023-03-09
    mysql查询 mysqljoin查询 mysql多次查询
  • MySQL JOIN关联查询的原理及优化
    目录1 关联查询的执行2 没有索引的算法1 关联查询的执行 关联查询的执行过程是:先遍历关联表t1(驱动表,全表扫描),然后根据从表t1中取出的每行数据中的a值,去表t2(被关联表,被驱动表)中查找满足条件的记录,可以走...
    99+
    2022-08-22
    MySQLJOIN关联查询 MySQLJOIN
  • MySQL性能调优之查询优化的方法
    本篇内容介绍了“MySQL性能调优之查询优化的方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、查询慢...
    99+
    2022-10-19
  • mysql update join如何优化update in查询效率
    这篇文章主要为大家展示了“mysql update join如何优化update in查询效率”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“mysql...
    99+
    2022-10-18
  • MySQL中(JOIN/ORDER BY)语句的查询过程及优化方法
    在MySQL查询语句过程和EXPLAIN语句基本概念及其优化中介绍了EXPLAIN语句,并举了一个慢查询例子: 可以看到上述的查询需要检查1万多记录,并且使用了临时表和filesort排序,这样的查询在用...
    99+
    2022-10-18
  • MySQL优化之慢查询日志
    慢查询日志概述 所谓慢查询日志,就是用于记录MySQL中响应时间超过设定阈值的SQL语句,通过打开慢查询开关,MySQL会将大于阈值的SQL记录在日志中,以便于分析性能。 慢查询日志选项默认是关闭的,如果要开启,则需要手动设置。 ...
    99+
    2021-08-28
    MySQL优化之慢查询日志
  • MySQL优化方案之开启慢查询日志
    目录前言设置慢查询日志测试附:日志分析工具mysqldumpslow总结前言 本方案只适应于小的项目、项目未上线或者紧急情况下可采用这种方式,一旦开启慢日志查询会增加数据库的压力,所...
    99+
    2022-11-12
  • MySQL,优化查询的方法
    对于数据库,优化查询的方法 1.使用索引   使用索引时,应尽量避免全表扫描,首先应考虑在 where 及 order by ,group by 涉及的列上建立索引。 2.优化SQL语句  1)分析查询语句:通过对查询语...
    99+
    2017-10-28
    MySQL,优化查询的方法
  • MySQL的查询优化方法
    本篇内容主要讲解“MySQL的查询优化方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL的查询优化方法”吧!1、简介    &nb...
    99+
    2022-10-18
  • mysql优化——查询优化
    这一篇mysql优化是注重于查询优化,根据mysql的执行情况,判断mysql什么时候需要优化,关于数据库开始阶段的数据库逻辑、物理结构的设计结构优化不是本文重点,下次再谈。 查看mysql语句的执行情况,判断是否需要进行优化 ...
    99+
    2016-09-05
    mysql优化——查询优化
  • mysql查询优化
    select * from a where id in (select id from b) 等价于: for select id from b for select 8 from...
    99+
    2022-02-02
    mysql查询优化
  • MySQL 查询优化
    查询优化常用策略  1、优化数据访问:应用程序应该减少对数据库的数据访问,数据库应该减少实际扫描的记录数     例如,Redis缓存,避免"selec&#...
    99+
    2022-10-18
  • Mysql数据库慢查询常用优化方式
    目录慢查询日志概念一、数据库中设置SQL慢查询1、mysql慢查询相关配置参数介绍2、实现配置步骤二、分析慢查询日志三、常见的慢查询优化1、索引没起作用的情况2、优化数据库结构3、分解关联查询4、优化LIMIT分页四、常...
    99+
    2023-05-05
    mysql如何优化慢查询 如何优化慢查询sql 优化mysql查询速度
  • Mysql常见的慢查询优化方式总结
    目录前言(1)数据库中设置SQL慢查询(2)分析慢查询日志         (3)常见的慢查询优化总结前言 这篇文章主要是就在公司实习的时候,对SQL优化工作作出的一些整...
    99+
    2023-05-05
    mysql如何优化查询 慢查询sql语句优化 MySQL查询优化
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作