了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表
一、为什么要用小表驱动大表
1、驱动表的定义
当进行多表连接查询时, [驱动表] 的定义为:
1)指定了联接条件时,满足查询条件的记录行数少的表为[驱动表]
2)未指定联接条件时,行数少的表为[驱动表](Important!)
忠告:如果你搞不清楚该让谁做驱动表、谁 join 谁,请让 MySQL 运行时自行判断
既然“未指定联接条件时,行数少的表为[驱动表]”了,而且你也对自己写出的复杂的 Nested Loop Join 不太有把握(如下面的实例所示),就别指定谁 left/right join 谁了,请交给 MySQL优化器 运行时决定吧。
如果您对自己特别有信心
2、mysql关联查询的概念:
MySQL 表关联的算法是 Nest Loop Join,是通过驱动表的结果集作为循环基础数据,然后一条一条地通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。
例: user表10000条数据,class表20条数据
select * from user u left join class c u.userid=c.userid
这样则需要用user表循环10000次才能查询出来,而如果用class表驱动user表则只需要循环20次就能查询出来
例:
select * from class c left join user u c.userid=u.userid
小结果集驱动大结果集
de.cel 在2012年总结说,不管是你,还是 MySQL,优化的目标是尽可能减少JOIN中Nested Loop的循环次数。
以此保证:永远用小结果集驱动大结果集(Important)!
二、优化联表查询
优化第一步之:根据驱动表的字段排序
left join不变,干嘛要根据非驱动表的字段排序呢?我们前面说过“对驱动表可以直接排序,对非驱动表(的字段排序)需要对循环查询的合并结果(临时表)进行排序!”的。
explain SELECT mb.id…… FROM mb LEFT JOIN mbei ON mb.id=mbei.mb_id INNER JOINu ON mb.uid=u.uid WHERE 1=1 ORDER BY mb.id DESC limit 0,10
也满足业务场景,做到了rows最小:
优化第二步:去除所有JOIN,让MySQL自行决定,explain第一张表就是驱动表,数据量比其它两张表都要小!
explain
SELECT mb.id……
FROM mb,mbei,u
WHERE
mb.id=mbei.mb_id
and mb.uid=u.user_id
order by mbei.apply_time desc
limit 0,10
立竿见影,驱动表一样是小表 mbei:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE mbei ALL mb_id (NULL) (NULL) (NULL) 13388 Using filesort
1 SIMPLE mb eq_ref PRIMARY,userid PRIMARY 4 mbei.mb_id 1
1 SIMPLE u eq_ref PRIMARY PRIMARY 4 mb.uid 1 Using index
三、总结
1、不要过于相信你的运气!
2、不要相信你的开发环境里SQL的执行速度!
3、请拿起 explain 武器,如果你看到以下现象,请优化:
1)出现了Using temporary
2)rows过多,或者几乎是全表的记录数
3)key 是 (NULL)
4)possible_keys 出现过多(待选)索引
了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表的更多相关文章
- 表A中一条记录的两个字段都对应于表B的同一个字段 如何查询?SQL, thinkphp[5]
表 A=approval_order, B=admin, 表A中technician_username, salesman_username 都是id号,中文名保存在admin表的nickname ...
- Django 中的select_related函数优化查询
参考链接: https://blog.csdn.net/secretx/article/details/43964607 在数据库有外键的时候,使用select_related()和prefech_r ...
- mysql 去除重复 Select中DISTINCT关键字的用法(查询两列,只去掉重复的一列)
在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的 ...
- 查询MS sql server里的所有表 SQL中所有列,说明,类型 查询总存储过程数
1.查询SQL中的所有表: Select TABLE_NAME FROM "你的数据库名称".INFORMATION_SCHEMA.TABLES Where TABLE_TYP ...
- [sql Server]除非另外还指定了TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效
今天遇到一个奇怪的问题,项目突然要从mysql切换到sql server数据库,包含order by 子句的嵌套子查询报错. 示例:select top 10 name,age,sex from ( ...
- {MySQL的逻辑查询语句的执行顺序}一 SELECT语句关键字的定义顺序 二 SELECT语句关键字的执行顺序 三 准备表和数据 四 准备SQL逻辑查询测试语句 五 执行顺序分析
MySQL的逻辑查询语句的执行顺序 阅读目录 一 SELECT语句关键字的定义顺序 二 SELECT语句关键字的执行顺序 三 准备表和数据 四 准备SQL逻辑查询测试语句 五 执行顺序分析 一 SEL ...
- SQL多表查询中的分页,字段组合综合实例解析
原文:http://www.jb51.net/article/28753.htm http://xuzhihong1987.blog.163.com/blog/static/2673158720098 ...
- 【原创】大叔问题定位分享(11)Spark中对大表子查询加limit为什么会报Broadcast超时错误
当两个表需要join时,如果一个是大表,一个是小表,正常的map-reduce流程需要shuffle,这会导致大表数据在节点间网络传输,常见的优化方式是将小表读到内存中并广播到大表处理,避免shuff ...
- 小表驱动大表, 兼论exists和in
给出两个表,A和B,A和B表的数据量, 当A小于B时,用exists select * from A where exists (select * from B where A.id=B.id) ex ...
- SELECT中(非常)常用的子查询操作
MySQL中的子查询 是在MySQL中经常使用到的一个操作,不仅仅是用在DQL语句中,在DDL语句.DML语句中也都会常用到子查询. 子查询的定义: 子查询是将一个查询语句嵌套在另一个查询语句中: 在 ...
随机推荐
- AngularJS 单元测试 Karma jasmine
当AngularJS项目越来越大时候,需要进行单元测试,可以先开发功能再进行测试,也可以先进行测试. 一.karma 是一个基于Node.js(先要安装)的JavaScript测试执行过程管理工具( ...
- Chubby是什么?
先简单的理解,以后补充: 为了解决hadoop分布式系统的一致性问题 ,有很多人提出很多protocol,其中就有有名的Paxos算法(Latex作者提出,算法需要学习), 但是Chubby并不是一个 ...
- LDO-AMS1117
AMS1117 1.是AMS艾默森公司简称.与AMS1117对应的IC有LM1117.AMS1117的最大输入电压为15V,而LM1117的极限是20V. 2.其输出电压有固定式(1.5V,1.8V, ...
- To datafix AR DATE
http://www.cnblogs.com/benio/archive/2012/07/07/2580203.html AR transactions should be created on 6- ...
- 为什么在UDP包中不能获取发包方的地址
首先,我们要先了解一下UDP包的结构. 图1 UDP报文格式 从图1,我们可以看出,从UDP包中,我们可以获取的信息只有源端口和目的地端口.我们不能获取到源IP因为报文中没有源IP.真正包含IP地址的 ...
- Linux下可视化空间分析工具ncdu
场景:磁盘空间占满后快速查找某个目录(子目录)占用空间大. ncdu /var (分析后按左右键查看即可)
- DataTable 快速导入数据库——百万条数据只需几秒
public void InsertTable(DataTable dt, string TabelName, DataColumnCollection dtColum) { string str = ...
- C# 读取资源文件.resx 中的xml资源
主要是以字符串的形式来读取xml,然后通过遍历读取节点,通过节点属性名称获取属性值 /// <summary> /// 初始化OPC参数配置 /// </summary> // ...
- 【文文殿下】【洛谷】分治NTT模板
题解 可以计算每一项对后面几项的贡献,然后考虑后面每一项,发现这是一个卷积,直接暴力NTT就行了,发现它是一个有后效性的,我们选择使用CDQ分治. Tips:不能像通常CDQ分治一样直接 每次递归两边 ...
- POJ 2696
#include<iostream> #define MAXN 1005 #include<stdio.h> using namespace std; int _m[MAXN] ...