MySQL 子查询(四)子查询的优化、将子查询重写为连接
MySQL 5.7 ref ——13.2.10.10优化子查询
十、子查询的优化
开发正在进行中,因此从长远来看,没有什么优化建议是可靠的。以下列表提供了一些您可能想要使用的有趣技巧。See also Section 8.2.2, “Optimizing Subqueries, Derived Tables, and View References”.
10.1 优化子查询中行的数量或顺序
SELECT * FROM t1 WHERE t1.column1 IN
(SELECT column1 FROM t2 ORDER BY column1); SELECT * FROM t1 WHERE t1.column1 IN
(SELECT DISTINCT column1 FROM t2); SELECT * FROM t1 WHERE EXISTS
(SELECT * FROM t2 LIMIT 1);
10.2 用子查询替换连接
SELECT DISTINCT column1
FROM t1 WHERE t1.column1 IN (
SELECT column1 FROM t2
);
用上面的语句替换这下面的:
SELECT DISTINCT t1.column1
FROM t1, t2
WHERE t1.column1 = t2.column1;
10.3
某些子查询可以转换为连接,以便与不支持子查询的旧版MySQL兼容。但是,在某些情况下,将子查询转换为连接可能会提高性能。
10.4 子句从外部移动到子查询内部
例如,用上面的查询代替下面的:
SELECT * FROM t1
WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2); /*代替*/ SELECT * FROM t1
WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);
另一个例子:
SELECT (SELECT column1 + 5 FROM t1) FROM t2; /*代替*/ SELECT (SELECT column1 FROM t1) + 5 FROM t2;
10.5 使用行子查询而不是相关子查询。
SELECT * FROM t1
WHERE (column1,column2) IN (SELECT column1,column2 FROM t2); /*代替*/ SELECT * FROM t1
WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1=t1.column1
AND t2.column2=t1.column2);
10.6
使用
NOT (a = ANY (...))
而不是
a <> ALL (...)
10.7
使用
x = ANY (table containing (1,2))
而不是
x=1 OR x=2.
10.8
使用
=ANY
而不是
EXISTS
10.9
对于始终返回一行的不相关子查询,IN 总是慢于 =
SELECT * FROM t1
WHERE t1.col_name = (SELECT a FROM t2 WHERE b = some_const); /*代替*/ SELECT * FROM t1
WHERE t1.col_name IN (SELECT a FROM t2 WHERE b = some_const);
这些技巧可能会导致程序变得更快或更慢。使用像BENCHMARK() 函数这样的MySQL工具,您可以了解在您自己的情况下有什么帮助。See Section 12.15, “Information Functions”.
MySQL自己也会做出一些优化:
- MySQL只执行一次不相关的子查询。使用EXPLAIN确保给定的子查询确实不相关。
- MySQL会重写IN,ALL,ANY和SOME子查询,这样是为了尝试提高子查询中的select-list列被索引的可能性。
- MySQL使用索引查找函数替换以下形式的子查询,EXPLAIN将其描述为特殊的连接类型(unique_subquery或index_subquery:
... IN (SELECT indexed_column FROM single_table ...)
- MySQL使用包含MIN()或MAX()的表达式增强以下表单的表达式,除非涉及NULL值或空集:
value {ALL|ANY|SOME} {> | < | >= | <=} (uncorrelated subquery)
例如,对这个WHERE子句
WHERE 5 > ALL (SELECT x FROM t)
优化器可能会像这样对待:
WHERE 5 > (SELECT MAX(x) FROM t)
See also MySQL Internals: How MySQL Transforms Subqueries.
十一、将子查询重写为连接
有时,除了使用子查询之外,还有其他方法可以测试一组值中的成员资格。
同样,在某些情况下,不仅可以将查询重写为没有子查询的语句,还可能比使用子查询更加高效。IN()构造器就是如此。
例如,这个查询:
SELECT * FROM t1 WHERE id IN (SELECT id FROM t2);
可以被重写为:
SELECT DISTINCT t1.* FROM t1, t2 WHERE t1.id=t2.id;
查询:
SELECT * FROM t1 WHERE id NOT IN (SELECT id FROM t2);
SELECT * FROM t1 WHERE NOT EXISTS (SELECT id FROM t2 WHERE t1.id=t2.id);
可以被重写为:
SELECT table1.*
FROM table1 LEFT JOIN table2 ON table1.id=table2.id
WHERE table2.id IS NULL;
LEFT [OUTER] JOIN可以比等效子查询更快,因为服务器可能能够更好地优化它——这个事实并非仅针对MySQL Server。
在SQL-92之前,外连接不存在,因此子查询是执行某些操作的唯一方法。今天,MySQL Server和许多其他现代数据库系统提供了广泛的外连接类型。
MySQL Server支持多表DELETE语句,可用于根据一个表甚至多个表中的信息同时有效地删除行。还支持多表UPDATE语句。See Section 13.2.2, “DELETE Syntax”, and Section 13.2.11, “UPDATE Syntax”.
MySQL 子查询(四)子查询的优化、将子查询重写为连接的更多相关文章
- 子查询四(在select子句中使用子查询)
示例一.查询出每个部门的编号,名称,位置,部门人数,平均工资 SELECT d.deptno,d.dname,d.loc, (SELECT COUNT(empno) FROM emp WHERE em ...
- 深入理解MySql子查询IN的执行和优化
IN为什么慢? 在应用程序中使用子查询后,SQL语句的查询性能变得非常糟糕.例如: SELECT driver_id FROM driver where driver_id in (SELECT dr ...
- MySQL之多表查询一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习
MySQL之多表查询 阅读目录 一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习 一 介绍 本节主题 多表连接查询 复合条件连接查询 子查询 首先说一下,我们写项目一般都会建 ...
- 警惕 MySql 更新 sql 的 WHERE 从句中的 IN() 子查询时出现的性能陷阱
警惕 MySql 更新 sql 的 WHERE 从句中的 IN() 子查询时出现的性能陷阱 以下文章来源:https://blog.csdn.net/defonds/article/details/4 ...
- Mysql常用sql语句(19)- in / exists 子查询
测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 前言 子查询在我们查询方法中是比较常用的,通过子查询可 ...
- 《MySQL必知必会学习笔记》:子查询
子查询 在開始了解子查询之前,首先做下准备工作,建立3个表, 一个是customers表,当中包含:客户名字.客户ID.客户Tel等. 一个是orders表,当中包含:订单号.客户ID.订单时间等. ...
- mysql索引优化比普通查询速度快多少
mysql索引优化比普通查询速度快多少 一.总结 一句话总结:普通查询全表查询,速度较慢,索引优化的话拿空间换时间,一针见血,所以速度要快很多. 索引优化快很多 空间换时间 1.软件层面优化数据库查询 ...
- mysql,存储引擎,事务,锁,慢查询,执行计划分析,sql优化
基础篇:MySql架构与存储引擎 逻辑架构图: 连接层: mysql启动后(可以把mysql类比为一个后台的服务器),等待客户端请求,当请求到来后,mysql建立一个一个线程处理(线程池则分配一个空线 ...
- Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化
参考书籍<mysql是怎样运行的> 非常推荐这本书,通俗易懂,但是没有讲mysql主从等内容 书中还讲解了本文没有提到的子查询优化内容, 本文只总结了常见的子查询是如何优化的 系列文章目录 ...
随机推荐
- 2018-2019-2 《网络对抗技术》 Exp6 信息搜集与漏洞扫描 20165222
1.实践目标 掌握信息搜集的最基础技能与常用工具的使用方法. 2.实践内容 (1)各种搜索技巧的应用 https://www.exploit-db.com/收集各种应用软件的漏洞,如tomcat服务器 ...
- git 和conding.net 超详细超简单安装
在做一下操作前,希望你能知道 1.什么是git? 可以参考https://blog.csdn.net/a909301740/article/details/81636662 如果还想多了解一下还可以参 ...
- 判断 js 类型的方式
1. typeof 可以判断出'string','number','boolean','undefined','symbol'但判断 typeof(null) 时值为 'object'; 判断数组和对 ...
- gis空间分析案例_7参数单坐标转换
gis空间分析案例_7参数单坐标转换 商务科技合作:向日葵,135-4855__4328,xiexiaokui#qq.com 功能: 对输入的单个坐标,利用7参数,一步进行坐标变换,使用极为直观,极大 ...
- iptables+ipset自动封闭和解封频繁访问web服务的恶意IP
转载于互联网 iptables直接针对ip进行封禁,在ip数量不大的时候是没什么问题的,但当有大量ip的时候性能会严重下降,iptables是O(N)的性能.而ipset就像一个集合,把需要封 ...
- Qt kdChart 甘特图案例
KDChart 甘特图在Qt中的加载使用案例,代码来自官方 mainwindow.h /******************************************************* ...
- 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_16-网关-过虑器
4.5 过虑器 Zuul的核心就是过虑器,通过过虑器实现请求过虑,身份校验等. 4.5.1 ZuulFilter 自定义过虑器需要继承 ZuulFilter,ZuulFilter是一个抽象类,需要覆盖 ...
- 123457123456#0#-----com.threeapp.BabyLeaningEnglish01----精品儿童学英语
com.threeapp.BabyLeaningEnglish01----精品儿童学英语
- HmacSHA256算法(C# 和 Java)
Java代码: /** * HmacSHA256算法,返回的结果始终是32位 * @param key 加密的键,可以是任何数据 * @param content 待加密的内容 * @return 加 ...
- LeetCode_190. Reverse Bits
190. Reverse Bits Easy Reverse bits of a given 32 bits unsigned integer. Example 1: Input: 000000101 ...