【MySQL】MySQL/MariaDB的优化器对in子查询的处理
参考:http://codingstandards.iteye.com/blog/1344833
上面参考文章中《高性能MySQL》第四章第四节在第三版中我对应章节是第六章第五节
最近分析生产环境慢查询,发现上线很久但是效率不高的查询
MySQL版本5.5.18
SELECT
loc.cell_no AS m_cellNo
...
FROM bs_loc loc LEFT JOIN st_stock_m m ON loc.cell_no = m.cell_no
WHERE
loc.zone_no = 'B12'
AND loc.WMS_PICKING_FLAG = 'cp'
AND m.cell_no in (SELECT cell_no FROM st_stock_m WHERE goods_no IN (''))
因为开发对这块的逻辑也不是很清楚,不分析逻辑上是否可以直接goods_no拿出来直接约束结果集,单纯从in子查询无法使用到索引来看MySQL优化器是如何去处理的
SELECT
`ma`.`loc`.`CELL_NO` AS `m_cellNo`
FROM `ma`.`bs_loc` `loc` JOIN `ma`.`st_stock_m` `m`
WHERE
((`ma`.`loc`.`ZONE_NO` ='B33') AND<in_optimizer>(`ma`.`m`.`CELL_NO`,
<EXISTS>
(SELECT1FROM `ma`.`st_stock_m` WHERE ((`ma`.`st_stock_m`.`GOODS_NO` ='') AND (<CACHE>(`ma`.`m`.`CELL_NO`) = `ma`.`st_stock_m`.`CELL_NO`))))
AND (`ma`.`loc`.`CELL_NO` = `ma`.`m`.`CELL_NO`))
执行计划

其实子查询返回的结果集最多不会超过3个,通常我们认为内部会按照使用结果集逐一去查,效率会很快,但实际上不是
以为内部的操作会是
步骤1:
SELECT group_concat(cell_no) FROM st_stock_m WHERE goods_no IN ('') into @cell_no;
步骤2
SELECT
loc.cell_no AS m_cellNo
... FROM bs_loc loc LEFT JOIN st_stock_m m ON loc.cell_no = m.cell_no
WHERE
loc.zone_no = 'B12'
AND loc.WMS_PICKING_FLAG = 'cp'
AND m.cell_no in (@cell_no);
按照《高性能MySQL》中所说:


把这个查询拿到MariaDB测试了一下,确实要比MySQL 5.5.18处理效果好很多。
SELECT
`ma`.`loc`.`CELL_NO` AS `m_cellNo`
FROM `ma`.`bs_loc` `loc` semi JOIN (`ma`.`st_stock_m`) JOIN `ma`.`st_stock_m` `m`
WHERE
(
(`ma`.`m`.`CELL_NO` = `ma`.`st_stock_m`.`CELL_NO`) AND
(`ma`.`loc`.`ZONE_NO` ='B33') AND
(`ma`.`st_stock_m`.`GOODS_NO` ='') AND
(`ma`.`loc`.`CELL_NO` = `ma`.`st_stock_m`.`CELL_NO`)
)
执行计划

MariaDB优化器改写后使用的semi join,这块MariaDB官网有部分说明:
https://mariadb.com/kb/en/mariadb/semi-join-materialization-strategy/
《MySQL技术内幕:SQL编程》中对于MariaDB优化器对于子查询和join的优化部分有说明

其他博文对于MySQL5.5以及MariaDB5.3优化器对比的文章:
http://blog.sina.com.cn/s/blog_aa8dc60801012pzc.html
http://www.server110.com/mariadb/201310/2245.html
【MySQL】MySQL/MariaDB的优化器对in子查询的处理的更多相关文章
- MYSQL优化派生表(子查询)在From语句中的
Mysql 在5.6.3中,优化器更有效率地处理派生表(在from语句中的子查询): 优化器推迟物化子查询在from语句中的子查询,知道子查询的内容在查询正真执行需要时,才开始物化.这一举措提高了性能 ...
- 【mysql的设计与优化专题(5)】慢查询详解
查询mysql的操作信息 show status -- 显示全部mysql操作信息 show status like "com_insert%"; -- 获得mysql的插入次数; ...
- mysql常用基础操作语法(十)~~子查询【命令行模式】
mysql中虽然有连接查询实现多表连接查询,但是连接查询的性能很差,因此便出现了子查询. 1.理论上,子查询可以出现在查询语句的任何位置,但实际应用中多出现在from后和where后.出现在from后 ...
- MySQL数据库(12)----ALL、ANY、SOME子查询
运算符 ALL 和 ANY 常与某个关系比较运算符结合在一起使用,以便测试列子查询的结果.它们会测试比较值与子查询返回的全部或部分值是否匹配.例如,当比较值小于或等于子查询返回的每个值时,<= ...
- MySQL 5.7 跟踪优化器
Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 5Server version ...
- 【MYSQL】update/delete/select语句中的子查询
update或delete语句里含有子查询时,子查询里的表不能在update或是delete语句中,如含有运行时会报错:但select语句里含有子查询时,子查询里的表可以在select语句中. 如:把 ...
- MySQL与MariaDB核心特性比较详细版v1.0(覆盖mysql 8.0/mariadb 10.3,包括优化、功能及维护)
注:本文严禁任何形式的转载,原文使用word编写,为了大家阅读方便,提供pdf版下载. MySQL与MariaDB主要特性比较详细版v1.0(不含HA).pdf 链接:https://pan.baid ...
- 深入理解MySql子查询IN的执行和优化
IN为什么慢? 在应用程序中使用子查询后,SQL语句的查询性能变得非常糟糕.例如: SELECT driver_id FROM driver where driver_id in (SELECT dr ...
- MySQL · 特性分析 · 优化器 MRR & BKA【转】
MySQL · 特性分析 · 优化器 MRR & BKA 上一篇文章咱们对 ICP 进行了一次全面的分析,本篇文章小编继续为大家分析优化器的另外两个选项: MRR & batched_ ...
随机推荐
- js方法收藏
1.验证非负数字 //onfocusout="checkQty(this);" function checkQty(obj) { //排除0开头的非法输入 if (obj.valu ...
- iframe替代方案
自己写一个pagelet框架.封装成JSP的Taglib. <tms:view header="common-header" footer="common-foot ...
- M2M协议
1, M2M协议 M2M是Machine-to-Machine/Man的简称,是一种以机器终端智能交互为核心的.网络化的应用与服务.M2M协议规定了人机和机器之间交互需要遵从的通信协议.随着科学技术的 ...
- Java注解教程:自定义注解示例,利用反射进行解析
Java注解能够提供代码的相关信息,同时对于所注解的代码结构又没有直接影响.在这篇教程中,我们将学习Java注解,如何编写自定义注解,注解的使用,以及如何使用反射解析注解. 注解是Java 1.5引入 ...
- Wex5案例使用JSON传输Thinkphp后端对接,以达成数据正常输出
初步接触Wex5,操作起来还是觉得比较复杂!而且教程不多,让我着实比较烦躁! 因此自己动手丰衣足食!还是比较实在的! 采用版本:WeX5应用快速开发框架V3.5正式版 我们使用Wex5的仿淘宝APP案 ...
- springmvc使用pojo和servlet原生api作为参数
一.Pojo作为参数: 实体: package com.hy.springmvc.entities; public class User { private String username; priv ...
- ContextLoaderListener与DispatcherServlet所加载的applicationContext的区别
spring通过在web.xml 中配置ContextLoaderListener 来加载context配置文件,在DispatcherServlet中也可以来加载spring context配置文件 ...
- iOS 播放声音文件
播放声音可以通过3中方式来完成. 1.AVAudioPlayer 使用简单方便,但只能播放本地音频,不支持流媒体播放. //初始化文件地址 NSBundle *bundle = [NSBundle m ...
- AOP切入点注解报错
开始学习AOP,出现如下的错误,最后发现是JDK与aspectj,aspectjweaver版本问题造成的.之后改成最新版本,代码运行正常. 利用这些特性可以进行代码的插入,比如权限,缓存结合mecm ...
- cwRsync 配置文件详解
GLOBAL PARAMETERS(全局参数) The first parameters in the file (before a [module] header) are the global p ...