浅谈SQL优化入门:2、等值连接和EXPLAIN(MySQL)
1、等值连接:显性连接和隐性连接
//WHERE方式
SELECT
vend_name,
prod_name,
prod_price,
quantity
FROM
vendors,
products,
orderitems
WHERE
vendors.vend_id = products.vend_id
AND
orderitems.prod_id = products.prod_id;
//WHERE方式
SELECT
vend_name,
prod_name,
prod_price,
quantity
FROM
vendors,
products,
orderitems
WHERE
vendors.vend_id = products.vend_id
AND
orderitems.prod_id = products.prod_id;
//INNER JOIN方式
SELECT
vend_name,
prod_name,
prod_price,
quantity
FROM
(vendors INNER JOIN products ON vendors.vend_id = prodcuts.vend_id)
INNER JOIN orderitems ON orderitems.prod_id = products.prod_id;
//INNER JOIN方式
SELECT
vend_name,
prod_name,
prod_price,
quantity
FROM
(vendors INNER JOIN products ON vendors.vend_id = prodcuts.vend_id)
INNER JOIN orderitems ON orderitems.prod_id = products.prod_id;
- 隐性连接,在FROM过程中对所有表进行笛卡儿积,最终通过WHERE条件过滤
- 显性连接,在每一次表连接时通过ON过滤,筛选后的结果集再和下一个表做笛卡儿积,以此循环
- 隐性连接,做所有表的笛卡儿积,共1000*1000*1000=1亿 行数据,再通过WHERE过滤,也就是说,三张表连接最终扫描的数据量高达1亿
- 显性连接,先做头两张表的笛卡儿积1000*1000=100万 行数据,通过ON条件筛选后的结果集(可能不到1000行)再和第三张表1000行数据做笛卡儿积
2、EXPLAIN
2.1 驱动表
- 指定了连接条件时,满足查询条件的记录行数少的表为驱动表
- 未指定连接条件时,行数少的表为驱动表
2.2 EXPLAIN
EXPLAIN
SELECT *
FROM
(SELECT * from t_rank AS r JOIN csic_delegation_dict AS dele ON r.commonCode_Delegation = dele.DELEGATION_CODE) tmp1
JOIN csic_event AS eve ON tmp1.commonCode_Event = eve.EVENT
EXPLAIN
SELECT *
FROM
(SELECT * from t_rank AS r JOIN csic_delegation_dict AS dele ON r.commonCode_Delegation = dele.DELEGATION_CODE) tmp1
JOIN csic_event AS eve ON tmp1.commonCode_Event = eve.EVENT
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-----------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-----------+
| 1 | PRIMARY | eve | ALL | NULL | NULL | NULL | NULL | 441 | |
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 504 |Using where|
| 2 | DERIVED | dele | ALL | NULL | NULL | NULL | NULL | 41 | |
| 2 | DERIVED | r | ALL | NULL | NULL | NULL | NULL | 539 |Using where|
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-----------+
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-----------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-----------+
| 1 | PRIMARY | eve | ALL | NULL | NULL | NULL | NULL | 441 | |
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 504 |Using where|
| 2 | DERIVED | dele | ALL | NULL | NULL | NULL | NULL | 41 | |
| 2 | DERIVED | r | ALL | NULL | NULL | NULL | NULL | 539 |Using where|
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-----------+
2.2.1 id
- id值较大的,执行优先级较高,且从上到下执行,且id值最大的组中,第一行为驱动表,如上图的table dele
- id值相同时,认为是一组,执行顺序从上到下
2.2.2 select_type
| 该字段的值 | 含义 |
| SIMPLE | 简单的SELECT,不适用UNION或子查询等 |
| PRIMARY | 查询中包含任何复杂的子部分,最外层的SELECT标记为PRIMARY |
| UNION | UNION中的第二个或后面的SELECT语句 |
| DEPENDENT UNION | UNION中的第二个或后面的SELECT语句,取决于外面的查询 |
| UNION RESULT | UNION的结果 |
| SUBQUERY | 子查询中的第一个SELECT |
| DEPENDENT SUBQUERY | 子查询中的第一个SELECT,取决于外面的查询 |
| DERIVED | 派生表的SELECT,FROM子句的子查询 |
| UNCACHEABLE SUBQUERY | 一个子查询的结果不能被缓存,必须重新评估外链接的第一行 |
2.2.3 table
- 当数据集市UNION的结果时,其值可能是<UNION M,N>,这里的M或N是id字段的值
- 当数据集来自派生表的SELECT,则显示的是derived*,这里的*是id字段的值,如:
mysql> EXPLAIN SELECT * FROM (SELECT * FROM ( SELECT * FROM t1 WHERE id=2602) a) b;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| 1 | PRIMARY | <derived2> | system | NULL | NULL | NULL | NULL | 1 | |
| 2 | DERIVED | <derived3> | system | NULL | NULL | NULL | NULL | 1 | |
| 3 | DERIVED | t1 | const | PRIMARY,idx_t1_id | PRIMARY | 4 | | 1 | |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
mysql> EXPLAIN SELECT * FROM (SELECT * FROM ( SELECT * FROM t1 WHERE id=2602) a) b;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| 1 | PRIMARY | <derived2> | system | NULL | NULL | NULL | NULL | 1 | |
| 2 | DERIVED | <derived3> | system | NULL | NULL | NULL | NULL | 1 | |
| 3 | DERIVED | t1 | const | PRIMARY,idx_t1_id | PRIMARY | 4 | | 1 | |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
2.2.4 type
| 该字段的值 | 含义 |
| ALL | 遍历全表 |
| index | 与ALL的区别在于只遍历索引树 |
| range | 表示只操作单表,且符合查询条件的记录不止1条 |
| ref | 表明本步执行计划操作的数据集中关联字段是索引字段,但不止1条记录符合上步执行计划操作的数据集的关联条件 |
| eq_ref | 表明本步执行计划操作的数据集中关联字段是索引字段,且只有1条记录符合上步执行计划操作的数据集的关联条件 |
| const | 表明上述"table"字段代表的数据集中,最多只有1行记录命中本步执行计划的查询条件 |
| system | system只是const值的一个特例,它表示本步执行计划要操作的数据集中只有1行记录 |
2.2.5 possible_keys
2.2.6 key
2.2.7 key_len
2.2.8 ref
2.2.9 rows
2.2.10 Extra
| 该字段的值 |
含义 |
| Using index | 表示使用索引,如果只有 Using index,说明他没有查询到数据表,只用索引表就完成了这个查询,这个叫覆盖索引。如果同时出现Using where,代表使用索引来查找读取记录, 也是可以用到索引的,但是需要查询到数据表。 |
| Using where | 表示条件查询,如果不读取表的所有数据,或不是仅仅通过索引就可以获取所有需要的数据,则会出现 Using where。如果type列是ALL或index,而没有出现该信息,则你有可能在执行错误的查询:返回所有数据。 |
| Using filesort | 不是“使用文件索引”的含义!filesort是MySQL所实现的一种排序策略,通常在使用到排序语句ORDER BY的时候,会出现该信息。 |
| Using temporary | 表示为了得到结果,使用了临时表,这通常是出现在多表联合查询,结果排序的场合。 |
3、STRAIGHT_JOIN


SQL查询时间为0.2s:
但是仍然需要引起注意的是,这种方式因为执行顺序被固化了,那么随着时间的推移,数据库中的数据分布随着业务开展而发生变化,很可能导致原本运行顺畅的SQL逐渐变得糟糕。
RESET QUERY CACHE;
RESET QUERY CACHE;
4、参考链接
附件列表
浅谈SQL优化入门:2、等值连接和EXPLAIN(MySQL)的更多相关文章
- 浅谈SQL优化入门:3、利用索引
0.写在前面的话 关于索引的内容本来是想写的,大概收集了下资料,发现并没有想象中的简单,又不想总结了,纠结了一下,决定就大概写点浅显的,好吧,就是懒,先挖个浅坑,以后再挖深一点.最基本的使用很简单,直 ...
- 浅谈SQL优化入门:1、SQL查询语句的执行顺序
1.SQL查询语句的执行顺序 (7) SELECT (8) DISTINCT <select_list> (1) FROM <left_table> (3) <join_ ...
- 浅谈sql优化
问题的发现: 菜鸟D在工作的时候发现项目的sql语句很怪,例如 : select a.L_ZTBH, a.D_RQ, a.VC_BKDM, (select t.vc_name from tb ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- 浅谈SQL Server内部运行机制
对于已经很熟悉T-SQL的读者,或者对于较专业的DBA来说,逻辑的增删改查,或者较复杂的SQL语句,都是非常简单的,不存在任何挑战,不值得一提,那么,SQL的哪些方面是他们的挑战 或者软肋呢? 那就是 ...
- 浅谈SQL Server数据内部表现形式
在上篇文章 浅谈SQL Server内部运行机制 中,与大家分享了SQL Server内部运行机制,通过上次的分享,相信大家已经能解决如下几个问题: 1.SQL Server 体系结构由哪几部分组成? ...
- 浅谈SQL Server---2
浅谈SQL Server内部运行机制 https://www.cnblogs.com/wangjiming/p/10098061.html 对于已经很熟悉T-SQL的读者,或者对于较专业的DBA来说, ...
- 浅谈SQL Server---1
浅谈SQL Server优化要点 https://www.cnblogs.com/wangjiming/p/10123887.html 1.SQL Server 体系结构由哪几部分组成? 2.SQL ...
- 浅谈SQL注入风险 - 一个Login拿下Server
前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...
随机推荐
- 几个简单的例子让你读懂什么是JAVA的堆栈跟踪
简单的来说,堆栈跟踪就是我们的程序在抛出异常时使用的方法调用列表. 简单的例子 通过问题中给出的示例,我们可以准确地确定应用程序中抛出异常的位置. 我们来看看堆栈跟踪: Exception in ...
- Maven详解(四)------ 常用的Maven命令
这章我们讲讲几个常用的 Maven 命令.由于执行命令是在工程的基础上来的,所以我们要先创建一个 Maven 工程,具体如何创建,在上一篇博客已经介绍了:http://www.cnblogs.com/ ...
- Django编写RESTful API(二):请求和响应
欢迎访问我的个人网站:www.comingnext.cn 前言 在上一篇文章,已经实现了访问指定URL就返回了指定的数据,这也体现了RESTful API的一个理念,每一个URL代表着一个资源.当然我 ...
- 80C51 数码管动态显示0~7
所使用的开发板 普中科技HC6800-ES V2.0 PC:win7 64位 编译软件: keil uversion2 烧写工具: 普中科技开发的PZ-ISP V1.82 烧写方式:热烧写 #incl ...
- 2017-04-21周C语言学习笔记
C语言学习笔记:... --------------------------------- C语言学习笔记:学习程度的高低取决于.自学能力的高低.有的时候生活就是这样的.聪明的人有时候需要.用笨的方法 ...
- BotVS开发基础—2.5 策略交互
一.代码部分 isOpen = False; # 是否 开仓 price = 0; # 全局变量 价格 amount = 0; # 全局变量 下单量 def exec_command(command) ...
- 一起来学Go --- (go的枚举以及数据类型)
枚举 枚举指一系列的相关的常量,比如下面关于一个星期的中每天的定义,通过上篇博文,我们可以用在const后跟一对圆括号的方式定义一组常量,这种定义法在go语言中通常用于定义枚举值.go语言并不支持众多 ...
- SpringMVC获取页面数据乱码的解决get/post
一.post请求方式的乱码 在web.xml中加入: <filter> <filter-name>CharacterEncodingFilter</filter-name ...
- javascript基础进阶——执行环境及作用域链
概念 执行环境 执行环境定义了变量或函数有权访问的其他函数,决定了他们各自的行为.每个执行环境都有一个与之关联的变量对象. 变量对象 环境中定义的所有变量和函数都保存在这个对象中. 全局执行环境 全局 ...
- 关于C#开发 windows服务进程
最近在做一个物联网项目,其中有一个模块是需要实现热水工程的自动化补水和回水功能 实现的方式有多种,我选用了VS C#的Windows服务方式. 首先是创建一个windows服务项目(名称随你喜欢的规范 ...