MySQL的JOIN(五):JOIN优化实践之排序
这篇博文讲述如何优化JOIN查询带有排序的情况。大致分为对连接属性排序和对非连接属性排序两种情况。插入测试数据。
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做内连接,连接条件是t1.id=t2.id,并对连接属性id属性进行排序(MySQL为主键id建立了索引)。
有两种选择,方式一[...ORDER BY t1.id],方式二[...ORDER BY t2.id],选哪种呢?
首先我们找出驱动表和被驱动表,按照小表驱动大表的原则,大表是t1,小表是t2,所以t2是驱动表,t1是非驱动表,t2驱动t1。然后进行分析,如果我们使用方式一的话,MySQL会先对t1进行排序然后执行表连接算法,如果我们使用方式二的话,只能执行表连接算法后对结果集进行排序(extra:using temporary),效率必然低下。
所以,当对连接属性进行排序时,应当选择驱动表的属性作为排序表中的条件。
-- 对被驱动表字段进行排序
EXPLAIN SELECT * FROM t1 INNER JOIN t2 ON t1.id =t2.id ORDER BY t1.id;
+----+-------+--------+---------+------+---------------------------------+
| id | table | type | key | rows | Extra |
+----+-------+--------+---------+------+---------------------------------+
| 1 | t2 | ALL | NULL | 100 | Using temporary; Using filesort |
| 1 | t1 | eq_ref | PRIMARY | 1 | NULL |
+----+-------+--------+---------+------+---------------------------------+ -- 对驱动表字段进行排序,没有Using temporary,也没有Using filesort
EXPLAIN SELECT * FROM t1 INNER JOIN t2 ON t1.id =t2.id ORDER BY t2.id;
+----+-------+--------+---------+------+-------+
| id | table | type | key | rows | Extra |
+----+-------+--------+---------+------+-------+
| 1 | t2 | index | PRIMARY | 100 | NULL |
| 1 | t1 | eq_ref | PRIMARY | 1 | NULL |
+----+-------+--------+---------+------+-------+
对非连接属性进行排序
现要求对t1和t2做内连接,连接条件是t1.id=t2.id,并对非连接属性t1的type属性进行排序,[...ORDER BY t1.type]。
首先我们找出驱动表和被驱动表,按照小表驱动大表的原则,大表是t1,小表是t2,所以MySQL Optimizer会用t2驱动t1。现在我们要对t1的type属性进行排序,t1是被驱动表,必然导致对连接后结果集进行排序Using temporary(比Using filesort更严重)。所以,能不能不用MySQL Optimizer,用大表驱动小表呢?
有请STRAIGHT_JOIN!
EXPLAIN SELECT * FROM t1 INNER JOIN t2 ON t1.id =t2.id ORDER BY t1.type;
+----+-------+--------+---------+------+---------------------------------+
| id | table | type | key | rows | Extra |
+----+-------+--------+---------+------+---------------------------------+
| 1 | t2 | ALL | NULL | 100 | Using temporary; Using filesort |
| 1 | t1 | eq_ref | PRIMARY | 1 | NULL |
+----+-------+--------+---------+------+---------------------------------+ -- Using temporary没有了,但是大表驱动小表,导致内循环次数增加,实际开发中要从实际出发,
-- 对此作出权衡。
EXPLAIN SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.id =t2.id ORDER BY t1.type;
+----+-------+--------+---------+-------+----------------+
| id | table | type | key | rows | Extra |
+----+-------+--------+---------+-------+----------------+
| 1 | t1 | ALL | NULL | 10000 | Using filesort |
| 1 | t2 | eq_ref | PRIMARY | 1 | NULL |
+----+-------+--------+---------+-------+----------------+
最后在MySQL的JOIN(一):用法那里挖了个坑,现在填上:INNER JOIN、JOIN、WHERE等值连接和STRAIGHT_JOIN都能表示内连接,那平时如何选择呢?一般情况下用INNER JOIN、JOIN或者WHERE等值连接,因为MySQL Optimizer会按照“小表驱动大表的策略”进行优化。当出现上述问题时,才考虑用STRAIGHT_JOIN
总结
《MySQL的JOIN》到此为止。
这系列博文讲述了JOIN的用法,JOIN的原理,以及在JOIN原理的基础上进行优化的手段。希望对大家有帮助吧:)
MySQL的JOIN(五):JOIN优化实践之排序的更多相关文章
- Mysql慢查询定位和优化实践分享
调优目标:提高io的利用率,减少无谓的io能力浪费. 1.打开慢查询日志定位慢sql: my.cnf: slow_query_log slow_query_log_file=mysql.slow lo ...
- MySQL 上亿大表优化实践
目录 背景 分析 select xxx_record语句 delete xxx_record语句 测试 实施 索引优化后 delete大表优化为小批量删除 总结 背景 XX实例(一主一从)xxx告警中 ...
- MySQL的JOIN(三):JOIN优化实践之内循环的次数
这篇博文讲述如何优化内循环的次数.内循环的次数受驱动表的记录数所影响,驱动表记录数越多,内循环就越多,连接效率就越低下,所以尽量用小表驱动大表.先插入测试数据. CREATE TABLE t1 ( i ...
- MySQL的JOIN(四):JOIN优化实践之快速匹配
这篇博文讲述如何优化扫描速度.我们通过MySQL的JOIN(二):JOIN原理得知了两张表的JOIN操作就是不断从驱动表中取出记录,然后查找出被驱动表中与之匹配的记录并连接.这个过程的实质就是查询操作 ...
- MYSQL join 优化 --JOIN优化实践之快速匹配
MySQL的JOIN(四):JOIN优化实践之快速匹配 优化原则:小表驱动大表,被驱动表建立索引有效,驱动表建立索引基本无效果.A left join B :A是驱动表,B是被驱动表:A right ...
- Mysql中Join用法及优化
Join的几种类型 笛卡尔积(交叉连接) 如果A表有n条记录,B表有m条记录,笛卡尔积产生的结果就会产生n*m条记录.在MySQL中可以为CROSS JOIN或者省略CROSS即JOIN,或者直接用f ...
- Mysql查询优化器之关于JOIN的优化
连接查询应该是比较常用的查询方式,连接查询大致分为:内连接.外连接(左连接和右连接).自然连接 下图展示了 LEFT JOIN.RIGHT JOIN.INNER JOIN.OUTER JOIN 相关的 ...
- MySQL的联结(Join)语法
MySQL的联结(Join)语法 1.内联结.外联结.左联结.右联结的含义及区别: 在讲MySQL的Join语法前还是先回顾一下联结的语法,呵呵,其实连我自己都忘得差不多了,那就大家一起温习吧(如 ...
- 《Mysql - 到底可不可以使用 Join ?》
一:Join 的问题? - 在实际生产中,使用 join 一般会集中在以下两类: - DBA 不让使用 Join ,使用 Join 会有什么问题呢? - 如果有两个大小不同的表做 join,应该用哪个 ...
随机推荐
- Unity3D --对撞机/碰撞器 介绍
碰撞器一般都用作触发器而用,刚体一般用作真实碰撞. 静态对撞机:一个对象有对撞机组件,没有刚体组件. 这种情况在场景中的静态物体应用较多,比如墙体,房屋等静止不动的物体. 物理引擎假设静态对撞机是不会 ...
- js原型学习
js中所有对象都存在一个隐式原型_ _proto_ _,指向创建这个对象的函数的原型prototype; 而函数的原型prototype都是Object函数的一个对象,也有隐式原型,指向的就是Obje ...
- Linux中mysql乱码问题
注意: 关于utf8和gbk的区别详细见:linux中文乱码问题解决办法 http://www.linuxidc.com/Linux/2010-04/25757.htm ,下面的配置中根据自己要求选择 ...
- Windows Firewall Setting
If our web site hosted on web server canot be accessed by other computer by public network, one of t ...
- MD5 in JAVA
using Apache Commons 需要引入org.apache.commons.codec.digest.DigestUtils这个包,pom.xml文件配置如下: <!-- https ...
- 跨server传输数据注意事项
我们需要模拟客服端 首先导入相关的jar包 文件,Jersey的相关jar包 实现客服端的代码为: @Test public void testClient() { //图片生成 ...
- 博文Contents<451--到999—>
积分=排名>2017-05-15这一天还真是厉害了.让我等了5个月时间... 前言:博客中的随笔文章.并非都是笔者的原创文章.有些是听别人说的.有些是书上摘录的.有些是百度的.有些是别人博客的文 ...
- Windows桌面快捷图标上的小箭头的恢复
Windows桌面快捷图标上的小箭头的恢复.. 桌面快捷图标上的小箭头的恢复: cmd /k reg add "HKEY_CLASSES_ROOT\lnkfile" /v IsSh ...
- Cell
首先需要创建一个model类,继承于NSObject: 定义两个属性: @property(nonatomic,retain)NSString imageName; @property(nonatom ...
- MySQL索引1
索引最大作用就是提高对表中数据的查询速度,就像书的目录那样重要,可以快速查到所需的知识. 上面是11万多条数据的表,使用语句查询,如: 耗时:0.108s 再比如: 用时:0.004s 接下来创建索引 ...