这篇博文讲述如何优化内循环的次数。内循环的次数受驱动表的记录数所影响,驱动表记录数越多,内循环就越多,连接效率就越低下,所以尽量用小表驱动大表。先插入测试数据。

    CREATE TABLE t1 (
id INT PRIMARY KEY AUTO_INCREMENT,
type INT
);
SELECT COUNT(*) FROM t1;
+----------+
| COUNT(*) |
+----------+
| 10000 |
+----------+
CREATE TABLE t2 (
id INT PRIMARY KEY AUTO_INCREMENT,
type INT
);
SELECT COUNT(*) FROM t2;
+----------+
| COUNT(*) |
+----------+
| 100 |
+----------+

内连接谁当驱动表

实际业务场景中,左连接、右连接可以根据业务需求认定谁是驱动表,谁是被驱动表。但是内连接不同,根据嵌套循环算法的思想,t1内连接t2和t2内连接t1所得结果集是相同的。那么到底是谁连接谁呢?谨记一句话即可,小表驱动大表可以减小内循环的次数。下面用        STRAIGHT_JOIN强制左表连接右表。By the way,STRIGHT_JOIN比较冷门,在这里解释下,其作用相当于内连接,不过强制规定了左表驱动右边。详情看这MySQL的JOIN(一):用法

    EXPLAIN SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.type=t2.type;
+----+-------+------+------+-------+----------------------------------------------------+
| id | table | type | key | rows | Extra |
+----+-------+------+------+-------+----------------------------------------------------+
| 1 | t1 | ALL | NULL | 10000 | NULL |
| 1 | t2 | ALL | NULL | 100 | Using where; Using join buffer (Block Nested Loop) |
+----+-------+------+------+-------+----------------------------------------------------+
EXPLAIN SELECT * FROM t2 STRAIGHT_JOIN t1 ON t2.type=t1.type;
+----+-------+------+------+-------+----------------------------------------------------+
| id | table | type | key | rows | Extra |
+----+-------+------+------+-------+----------------------------------------------------+
| 1 | t2 | ALL | NULL | 100 | NULL |
| 1 | t1 | ALL | NULL | 10000 | Using where; Using join buffer (Block Nested Loop) |
+----+-------+------+------+-------+----------------------------------------------------+

对于第一条查询语句,t1是驱动表,其有10000条记录,内循环也就有10000次,这还得了?
对于第二条查询语句,t2是驱动表,其有100条记录,内循环100次,感觉不错,我喜欢!
这些SQL语句的执行时间也说明了,当内连接时,务必用小表驱动大表。

最佳实践:直接让MySQL去判断

但是,表的记录数是会变化的,有没有一劳永逸的写法?当然有啦,MySQL自带的Optimizer会优化内连接,优化策略就是上面讲的小表驱动大表。所以,以后写内连接不要纠结谁内连接谁了,直接让MySQL去判断吧。

    EXPLAIN SELECT * FROM t1 INNER JOIN t2 ON t1.type=t2.type;
EXPLAIN SELECT * FROM t2 INNER JOIN t1 ON t1.type=t2.type;
EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.type=t2.type;
EXPLAIN SELECT * FROM t2 JOIN t1 ON t1.type=t2.type;
EXPLAIN SELECT * FROM t1,t2 WHERE t1.type=t2.type;
EXPLAIN SELECT * FROM t2,t1 WHERE t1.type=t2.type;
+----+-------+------+------+--------+----------------------------------------------------+
| id | table | type | key | rows | Extra |
+----+-------+------+------+--------+----------------------------------------------------+
| 1 | t2 | ALL | NULL| 100 | NULL |
| 1 | t1 | ALL | NULL | 110428 | Using where; Using join buffer (Block Nested Loop) |
+----+-------+------+------+--------+----------------------------------------------------+

上面6条内连接SQL,MySQL的Optimizer都会进行优化。

MySQL的JOIN(三):JOIN优化实践之内循环的次数的更多相关文章

  1. Mysql慢查询定位和优化实践分享

    调优目标:提高io的利用率,减少无谓的io能力浪费. 1.打开慢查询日志定位慢sql: my.cnf: slow_query_log slow_query_log_file=mysql.slow lo ...

  2. MySQL 上亿大表优化实践

    目录 背景 分析 select xxx_record语句 delete xxx_record语句 测试 实施 索引优化后 delete大表优化为小批量删除 总结 背景 XX实例(一主一从)xxx告警中 ...

  3. MySQL的JOIN(四):JOIN优化实践之快速匹配

    这篇博文讲述如何优化扫描速度.我们通过MySQL的JOIN(二):JOIN原理得知了两张表的JOIN操作就是不断从驱动表中取出记录,然后查找出被驱动表中与之匹配的记录并连接.这个过程的实质就是查询操作 ...

  4. MySQL的JOIN(五):JOIN优化实践之排序

    这篇博文讲述如何优化JOIN查询带有排序的情况.大致分为对连接属性排序和对非连接属性排序两种情况.插入测试数据. CREATE TABLE t1 ( id INT PRIMARY KEY AUTO_I ...

  5. MYSQL join 优化 --JOIN优化实践之快速匹配

    MySQL的JOIN(四):JOIN优化实践之快速匹配 优化原则:小表驱动大表,被驱动表建立索引有效,驱动表建立索引基本无效果.A left join B :A是驱动表,B是被驱动表:A right ...

  6. mysql性能调优——Query优化

    上节谈了关于mysql锁定机制的优化方案,下面来谈一下Query优化——Mysql Query Optimizer 当Mysql Query Optimizer接受到从Query Parser过来的Q ...

  7. Mysql中Join用法及优化

    Join的几种类型 笛卡尔积(交叉连接) 如果A表有n条记录,B表有m条记录,笛卡尔积产生的结果就会产生n*m条记录.在MySQL中可以为CROSS JOIN或者省略CROSS即JOIN,或者直接用f ...

  8. Mysql查询优化器之关于JOIN的优化

    连接查询应该是比较常用的查询方式,连接查询大致分为:内连接.外连接(左连接和右连接).自然连接 下图展示了 LEFT JOIN.RIGHT JOIN.INNER JOIN.OUTER JOIN 相关的 ...

  9. hive join的三种优化方式

    原网址:https://blog.csdn.net/liyaohhh/article/details/50697519 hive在实际的应用过程中,大部份分情况都会涉及到不同的表格的连接, 例如在进行 ...

随机推荐

  1. Eclipse、maven项目常见问题

    阿里云maven仓库地址: <mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorOf> &l ...

  2. Java高并发如何解决

    Java高并发如何解决 对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题,但话又说回来了,既然逃避不掉,那我们就坦然面对吧 ...

  3. HTML <img>标签 创建图像映射

    初级前端一枚 下面代码是在图片上创建图像映射 自己整理了下 做个笔记 希望也可以帮助后来学习的朋友! <map name="planetmap"> <area s ...

  4. Apache Kafka系列(二) 命令行工具(CLI)

    Apache Kafka命令行工具(Command Line Interface,CLI),下文简称CLI. 1. 启动Kafka 启动Kafka需要两步: 1.1. 启动ZooKeeper [roo ...

  5. tps 与 事务平均响应时间关系对答

    在网上看到一篇文章,tps 与 事务平均响应时间关系对答.可以帮助能更清楚的了解二者之间的关系. 问者:每秒处理的事务数和事务的平均响应时间 怎么个关系,有关系吗 kaku21:举个例子:一个高速路 ...

  6. Linux用户深度管理

      linux系统是多任务.多用户的系统. 用户.用户组的概念 每个文件和进程,都需要对应一个用户和用户组. linux系统是通过UID和GID来是识别用户和组的. 其中用户名等同于人名(人类识别), ...

  7. innodb和myisam存储引擎插入速度

    --innodb和myisam存储引擎插入速度 ------------------------------------2014/05/21 MySQL 5.6 全部默认设置,插入数据9999条,性能 ...

  8. 一些常用的集合工具的代码块(缓慢更新XD)

    鱼的记忆   我发现在项目中常常要用到一些集合的处理,不同的项目我经常会编写自己的集合工具代码块,后来我发现我总是在写一样的代码块(可能是我记性不好吧:),毕竟鱼的记忆只有7秒),所以我意识到了是时候 ...

  9. python 符合Python风格的对象

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 25.0px Helvetica } 对象表示形式 每门面向对象的语言至少都有一种获取对象的字符串表示形式的 ...

  10. Appium元素定位

    一.定位工具(UIAutomator) 运行系统条件:      1)Android Studio      2)系统版本:sdk 要求api18以及以上 打开:Android SDK  ---Too ...