MySQL in查询优化
https://blog.csdn.net/gua___gua/article/details/47401621
MySQL in查询优化<一>
- 5137
开发说他写了个SQL特别慢,让看看。
- select * from t_channel where id_ in(select distinct cdbh from sjkk_gcjl where jgsj>'2015-01-02 08:00:00' and jgsj<'2015-01-02 12:00:00');
- ......
- 30min+
然后我查询内部SQL,只需要3s+
- mysql> select distinct cdbh from sjkk_gcjl where jgsj>'2015-01-02 08:00:00' and jgsj<'2015-01-02 12:00:00';
- .....
- 1755 rows in set (3.30 sec)
- mysql> select count(*) from t_channel;
- ....
- 12062 rows in set (0.70 sec)
开发写的SQL为啥那么慢呢?看看执行计划
- explain extended select * from t_channel where id_ in(select distinct cdbh from sjkk_gcjl where jgsj>'2015-01-02 08:00:00' and jgsj<'2015-01-02 12:00:00');
- +----+--------------------+-----------+-------+---------------+----------+---------+------+--------+----------+------------------------------+
- | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
- +----+--------------------+-----------+-------+---------------+----------+---------+------+--------+----------+------------------------------+
- | 1 | PRIMARY | t_channel | ALL | NULL | NULL | NULL | NULL | 12062 | 100.00 | Using where |
- | 2 | DEPENDENT SUBQUERY | sjkk_gcjl | range | idx_jgsj | idx_jgsj | 8 | NULL | 731868 | 100.00 | Using where; Using temporary |
- +----+--------------------+-----------+-------+---------------+----------+---------+------+--------+----------+------------------------------
看看数据库转换后的语句
- mysql> show warnings;
- SELECT
- `shanghai_full`.`t_channel`.`ID_` AS `ID_`,
- `shanghai_full`.`t_channel`.`Code_` AS `Code_`,
- ...... --这里会列出所有字段
- FROM
- `shanghai_full`.`t_channel`
- WHERE
- < in_optimizer > (
- `shanghai_full`.`t_channel`.`ID_` ,< EXISTS > (
- SELECT DISTINCT
- 1
- FROM
- `shanghai_full`.`sjkk_gcjl`
- WHERE
- (
- (
- `shanghai_full`.`sjkk_gcjl`.`jgsj` > '2015-01-02 08:00:00'
- )
- AND (
- `shanghai_full`.`sjkk_gcjl`.`jgsj` < '2015-01-02 12:00:00'
- )
- AND (
- < CACHE > (
- `shanghai_full`.`t_channel`.`ID_`
- ) = `shanghai_full`.`sjkk_gcjl`.`cdbh`
- )
- )
- )
- );
可见,经过mysql优化器后,in 给转换成exists的方式(mysql认为换成exists更快,呵呵)。
慢的原因:走了exists,查询把外表t_channel做为主表进行全表扫描,每扫描一行数据,然后对子查询进行查询看这条数据是否符合条件。
特别说明:mysql版本是5.5。在5.6中mysql做了改进,将in的这种查询转换为了join。
优化方式一(将in查询转换为连接查询)
- select t1.* from t_channel t1,(select distinct cdbh from sjkk_gcjl where jgsj>'2015-01-02 08:00:00' and jgsj<'2015-01-02 12:00:00') t2 where t1.id_=t2.cdbh;
- ......
- 1264 rows in set (3.30 sec)
- mysql> explain extended select t1.* from t_channel t1,(select distinct cdbh from sjkk_gcjl where jgsj>'2015-01-02 08:00:00' and jgsj<'2015-01-02 12:00:00') t2 where t1.id_www.255055.cn/ =t2.cdbh;
- +----+-------------+------------+--------+---------------+----------+---------+---------+--------+----------+------------------------------+
- | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
- +----+-------------+------------+--------+---------------+----------+---------+---------+--------+----------+------------------------------+
- | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 1755 | 100.00 | |
- | 1 | PRIMARY | t1 www.boshenyl.cn | eq_ref | PRIMARY,ID_ | PRIMARY | 74 | t2.cdbh | 1 | 100.00 | Using where |
- | 2 | DERIVED | sjkk_gcjl | range | idx_jgsj | idx_jgsj | 8 | NULL | 731868 | 100.00 | Using where; Using temporary |
- +----+-------------+------------+--------+---------------+----------+---------+---------+--------+----------+------------------------------+
- mysql> show warnings;
- SELECT
- `shanghai_full`.`t1`.`ID_` AS `ID_`,
- ........ ---这里会列出所有字段FROM
- `shanghai_full`.`t_channel` `t1`
- JOIN (
- SELECT DISTINCT
- `shanghai_full`.`sjkk_gcjl`.`cdbh` AS `www.cnzhaotai.com cdbh`
- FROM
- `shanghai_full`.www.fengshen157.com `sjkk_gcjl`
- WHERE
- (
- (
- `shanghai_full`.`sjkk_gcjl`.`jgsj` > '2015-01-02 08:00:00'
- )
- AND (
- `shanghai_full`.`sjkk_gcjl`.`jgsj` < '2015-01-02 12:00:00'
- )
- )
- ) `t2`
- WHERE
- (
- `shanghai_full`.`t1`.`ID_` = www.taohuayuan178.com `t2`.`cdbh`
- );
优化方式二(使用memory引擎的临时表)
- mysql> create temporary table tmp_www.yibaoyule1.com channel engine=memory (select distinct cdbh from sjkk_gcjl where jgsj>'2015-01-02 08:00:00' and jgsj<'2015-01-02 12:00:00');
- Query OK, 1755 rows affected (9.00 sec)
- Records: 1755 Duplicates: 0 Warnings: 0
- mysql> select * from t_channel where id_ in(select * from tmp_channel);
- .....
- 1264 rows in set (0.26 sec)
- mysql> explain extended select * from t_channel where id_ in(select * from tmp_channel);
- +----+--------------------+-------------+------+---------------+------+---------+------+------+----------+-------------+
- | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
- +----+--------------------+-------------+------+---------------+------+---------+------+------+----------+-------------+
- | 1 | PRIMARY | t_channel | ALL | NULL | NULL | NULL | NULL | 3224 | 100.00 | Using where |
- | 2 | DEPENDENT SUBQUERY | tmp_channel | ALL | NULL | NULL | NULL | NULL | 20 | 100.00 | Using where |
- +----+--------------------+-------------+------+---------------+------+---------+------+------+----------+-------------+
- mysql> show warnings;
- | Note | 1003 | select `vmc_jiaqi`.`t_channel`.`ID_` AS `ID_`,`vmc_jiaqi`.`t_channel`.`Code_` AS `Code_`,`vmc_jiaqi`.`t_channel`.`HostId_` AS `HostId_`,`vmc_jiaqi`.`t_channel`.`RoadMonitorStationId_` AS `RoadMonitorStationId_`,`vmc_jiaqi`.`t_channel`.`ChannelNo_` AS `ChannelNo_`,`vmc_jiaqi`.`t_channel`.`Name_` AS `Name_`,`vmc_jiaqi`.`t_channel`.`ChannelType_` AS `ChannelType_`,`vmc_jiaqi`.`t_channel`.`Ext_` AS `Ext_`,`vmc_jiaqi`.`t_channel`.`DeviceAddress_` AS `DeviceAddress_`,`vmc_jiaqi`.`t_channel`.`MinSpeed_`www.mhylpt.comS `MinSpeed_`,`vmc_jiaqi`.`t_channel`.`MaxSpeed_` AS `MaxSpeed_`,`vmc_jiaqi`.`t_channel`.`LimitMinRatio_` AS `LimitMinRatio_`,`vmc_jiaqi`.`t_channel`.`LimitMaxRatio_` AS `LimitMaxRatio_`,`vmc_jiaqi`.`t_channel`.`Direction_` AS `Direction_`,`vmc_jiaqi`.`t_channel`.`JcDirection_` AS `JcDirection_`,`vmc_jiaqi`.`t_channel`.`LaneNum_` AS `LaneNum_`,`vmc_jiaqi`.`t_channel`.`FrameDropNum_` AS `FrameDropNum_`,`vmc_jiaqi`.`t_channel`.`RecogizeRectLeft_` AS `RecogizeRectLeft_`,`vmc_jiaqi`.`t_channel`.`RecogizeRectTop_` AS `RecogizeRectTop_`,`vmc_jiaqi`.`t_channel`.`RecogizeRectWidth_` AS `RecogizeRectWidth_`,`vmc_jiaqi`.`t_channel`.`RecogizeRectHeight_` AS `RecogizeRectHeight_`,`vmc_jiaqi`.`t_channel`.`RmpServerIp_` AS `RmpServerIp_`,`vmc_jiaqi`.`t_channel`.`RmpServerPort_` AS `RmpServerPort_`,`vmc_jiaqi`.`t_channel`.`VirtualGateServerId_` AS `VirtualGateServerId_`,`vmc_jiaqi`.`t_channel`.`LaneType_` AS `LaneType_`,`vmc_jiaqi`.`t_channel`.`DeviceType_` AS `DeviceType_`,`vmc_jiaqi`.`t_channel`.`ManufacturerId_` AS `ManufacturerId_`,`vmc_jiaqi`.`t_channel`.`IsLocalSavePicture_` AS `IsLocalSavePicture_`,`vmc_jiaqi`.`t_channel`.`OrderNO_` AS `OrderNO_`,`vmc_jiaqi`.`t_channel`.`channelStatus` AS `channelStatus` from `vmc_jiaqi`.`t_channel` where <in_optimizer>(`vmc_jiaqi`.`t_channel`.`ID_`,<exists>(select 1 from `vmc_jiaqi`.`tmp_channel` where (<cache>(`vmc_jiaqi`.`t_channel`.`ID_`) = `vmc_jiaqi`.`tmp_channel`.`cdbh`)))
注意:第二种方式还是使用了exists的执行方式,所以这种方式没有第一种方式好,在特定的条件下可能会有用处,
MySQL in查询优化的更多相关文章
- php mysql 一个查询优化的简单例子
PHP+Mysql是一个最经常使用的黄金搭档,它们俩配合使用,能够发挥出最佳性能,当然,如果配合Apache使用,就更加Perfect了. 因此,需要做好对mysql的查询优化.下面通过一个简单的例子 ...
- WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)
WebAPI调用笔记 前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...
- 查询优化 | MySQL慢查询优化
Explain查询:rows,定位性能瓶颈. 只需要一行数据时,使用LIMIT1. 在搜索字段上建立索引. 使用ENUM而非VARCHAR. 选择区分度高的列作为索引. 采用扩展索引,而不是新建索引 ...
- MySQL 慢查询优化
为什么查询速度会慢 1.慢是指一个查询的响应时间长.一个查询的过程: 客户端发送一条查询给服务器 服务器端先检查查询缓存,如果命中了缓存,则立可返回存储在缓存中的结果.否则进入下一个阶段 服务器端进行 ...
- MySQL SQL查询优化技巧详解
MySQL SQL查询优化技巧详解 本文总结了30个mysql千万级大数据SQL查询优化技巧,特别适合大数据里的MYSQL使用. 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 ...
- 关于mysql的查询优化
由于工作原因,最近甲方客户那边多次反应了他们那边的系统查询速度慢,经过排除之后,发现他们那边的数据库完全没有用到索引,简直坑得一笔,通过慢查询日志分析,为数据表建立了适当的索引之后,查询速度明显的提高 ...
- 《MySQL慢查询优化》之SQL语句及索引优化
1.慢查询优化方式 服务器硬件升级优化 Mysql服务器软件优化 数据库表结构优化 SQL语句及索引优化 本文重点关注于SQL语句及索引优化,关于其他优化方式以及索引原理等,请关注本人<MySQ ...
- MySQL 的查询优化
说起 MySQL 的查询优化,相信大家收藏了一堆奇技淫巧:不能使用 SELECT *.不使用 NULL 字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解它背 ...
- MySQL慢查询优化
MySQL数据库是常见的两个瓶颈是CPU和I/O的瓶颈,CPU在饱和的时候一般发生在大量数据进行比对或聚合时.磁盘I/O瓶颈发生在装入数据远大于内存容量的时候,如果应用分布在网络上,那么查询量相当大的 ...
随机推荐
- 【linux下dhcp服务的简单搭建及优化部署】
dhcp server: 1::vim /etc/sysconfig/network-scripts/ifcfg-scfg:配置 server的 static IP: 2:vim /etc/dhcpd ...
- RubyMine常用快捷键
一级必会 Shift+F10:运行running Ctrl+Alt+R:弹出RakeCtrl+Alt+G:弹出GenerateCtrl+Alt+L:格式化代码Alt+F1:切换视图(Project, ...
- (数据科学学习手札35)tensorflow初体验
一.简介 TensorFlow时谷歌于2015年11月宣布在Github上开源的第二代分布式机器学习系统,目前仍处于快速开发迭代中,有大量的新功能新特性在陆续研发中: TensorFlow既是一个实现 ...
- linux execl()函数
关于execl()函数族的用法不在赘述,其他博主介绍的很详细.下面说下作者在使用该函数时所犯的错误: 作者想通过使用execl()函数在子进程中调用其他函数,起初楼主是 这样用的: if((a = e ...
- Spark是什么
官方直达电梯 Spark一种基于内存的通用的实时大数据计算框架(作为MapReduce的另一个更优秀的可选的方案) 通用:Spark Core 用于离线计算,Spark SQL 用于交互式查询,Spa ...
- Windows 10 下如何彻底关闭 Hyper-V 服务(翻外篇)
原文:Windows 10 下如何彻底关闭 Hyper-V 服务(翻外篇) windows禁用/启用hyper-V,解决hyper-V与模拟器同时启用时造成冲突 我是这样解决的,以管理员身份运行命令提 ...
- LARK BOARD开发板试用第一篇-上电测试学习
1. 先看下板子外观,做工很不错 2. 主芯片的型号是,SoC 为 Cyclone V SX 系列的 5CSXFC6D6F31,不仅在芯片中包含传统的 FPGA 架构,还集成了基于 ARM Corte ...
- 3招搞定APP注册作弊
在说如何应对之前,易盾先给各位盾友梳理移动端APP可能遇到哪些作弊风险.1. 渠道商刷量,伪造大量的下载量和装机量,但没有新用户注册:2. 对于电商.P2P.外卖等平台,会面临散户或者团队刷子的注册- ...
- Django笔记 —— 表单(form)
最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过.Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧- 本篇笔记(其 ...
- join ,left join ,right join有什么区别
join等价于inner join内连接,是返回两个表中都有的符合条件的行. left join左连接,是返回左表中所有的行及右表中符合条件的行.(左表为主表) right join右连接,是返回右表 ...