浅谈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有注入,随便都 ...
随机推荐
- JQuery对联广告
html--------------------------------------------------------------------------------------<!DOCTY ...
- vue开发项目的坑
[Vue warn]: Do not use built-in or reserved HTML elements as component id: MenuItem [Vue warn]: Do n ...
- python中的collections.namedtuple
简介 collections.namedtuple是一个工厂方法,它可以动态的创建一个继承tuple的子类.跟tuple相比,返回的子类可以使用名称来访问元素. 使用方法 用一个例子来介绍: > ...
- java创建泛型数组
java中创建泛型数组并不是不可能,创建泛型数组通过反射,给构造函数传递两个参数,一个类型标记,一个数组大小.' 简单Demo如下: import java.lang.reflect.Array; / ...
- oracle那些基本知识
Oracle创建表空间.创建用户以及授权 .查看权限 @ rownum 分页查询 它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限 ...
- Webservice优缺点总结
优点: 1 .采用xml支持跨平台远程调用. 2.基于http的soap协议,可跨越防火墙. (因为SOAP一般使用HTTP协议,而服务器的这个协议一般都是开放的,而且是可以穿过防火墙的) 3.支持面 ...
- [js高手之路]gulp教程-从入门到项目中快速上手使用
在这之前,我已经分享过一个webpack的全系列,相对于webpack, gulp使用和配置起来非常的简单. gulp是什么? gulp 是基于 node 实现 Web 前端自动化开发的工具,利用它能 ...
- jenkins+gitlab+sonar+testng构建持续集成测试环境(配置干货篇)
几个工具的安装部分就不在此介绍了! jenkins配置: 1.插件安装 2.root私钥配置 3.构建job配置 4.部署job配置 5.测试job配置 7.jenkins全局工具配置 8.jenki ...
- [转载]浏览器事件window.onload、onfocus、onblur、ons
原文地址:浏览器事件window.onload.onfocus.onblur.onscroll和resize作者:lilyxiao <html> <head> <titl ...
- css预处理器less和scss之less介绍(一)
第一次发的标题有误,重发一遍,抱歉了 一.less基础语法 1.声明变量:@变量名:变量值 使用变量:@变量名 例如 @color : #ff0000; @length : 100px; #div1{ ...