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

    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. 让这三个月来的更猛烈些吧,前端react同构项目

    昨天一篇文章讲述了我在这三个月中由.net到java的过程,其中踩坑填坑的细节真不是三言两语可以道尽,而完成时的喜悦也远非寻常可比(仅次于涨工资).然而到这并不算完结,作为前后端分离的忠实粉丝,我认为 ...

  2. HPU--1280 Divisible

    题目描述 给定一个很大的整数,我想知道它能否被9整除. 输入 有t组测试数据,每组数据给定一个整数N不存在前导0.(1 <= t <= 20,1 <= N <= 10^200) ...

  3. [Scoi2014]方伯伯的玉米田 二维树状数组+动态规划

    考试最后半个小时才做这道题.十分钟写了个暴力还写挂了..最后默默输出n.菜鸡一只. 这道题比较好看出来是动规.首先我们要明确一点.因为能拔高长度任意的一段区域,所以如果从i开始拔高,那么一直拔高到n比 ...

  4. C#使用Xamarin开发可移植移动应用(3.Xamarin.Views控件)附源码

    前言 系列目录 C#使用Xamarin开发可移植移动应用目录 源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. .NET ...

  5. 链接样式L-O-H-A

    伪类可以链接起来使用,即不用在乎顺序 :link{color:blue;} :visited{color:purple;} :link:hover{color:red;} :visited:hover ...

  6. Python获取区域面积

    import cv2 import numpy as np def get_leave_areas(image): img = cv2.imread(image) GrayImage = cv2.cv ...

  7. Luogu P1649 [USACO07OCT]障碍路线Obstacle Course

    题目描述 Consider an N x N (1 <= N <= 100) square field composed of 1 by 1 tiles. Some of these ti ...

  8. MySQL中的数据类型及创建

    MySQL创建: 1.创建数据库create database test2; 2.删除数据库drop database test2;3.创建表create table ceshi(    ids in ...

  9. php 单引号,双引号,反引号区别

    PHP中单引号,双引号,反引号具有不同的含义,最大的几项区别如下: 一.单引号中,任何变量($var).特殊转义字符(如"\t \r \n"等)不会被解析,因此PHP的解析速度更快 ...

  10. Java静态绑定与动态绑定

    程序绑定的概念: 绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来.对java来说,绑定分为静态绑定和动态绑定:或者叫做前期绑定和后期绑定. 静态绑定: 在程序执行前方法已经被绑定(也就是说 ...