MySQL IN和EXISTS的效率问题,以及执行优化
网上可以查到很多这样的说法:
如果查询的两个表大小相当,那么用in和exists差别不大。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:
例如:表A(小表),表B(大表)
1:
select * from A where cc in (select cc from B) 效率低,用到了A表上cc列的索引;
select * from A where exists(select cc from B where cc=A.cc) 效率高,用到了B表上cc列的索引。
相反的
2:
select * from B where cc in (select cc from A) 效率高,用到了B表上cc列的索引;
select * from B where exists(select cc from A where cc=B.cc) 效率低,用到了A表上cc列的索引。
将下面的语句执行优化:
select count(uid) from user where uid in (SELECT did FROM demo);
select count(uid) from user where exists (SELECT 1 FROM demowhere demo.did = user.uid);
1.注意慢的原因就是内部每次与外部比较时,都需要遍历一次表操作,可以采用另外一个方法,在嵌套一层子查询,避免多次遍历操作
SELECT count(did) FROM demo where exists (SELECT uid FROM (SELECT uid from user) as b where b.uid = demo.did);
2.第二种优化就是先将子查询里的语句执行,使用GROUP_CONCAT将字段连接起来,
如果字符串长度不够可以使用:SET SESSION group_concat_max_len = 102400;
原sql:
SELECT
c.id
FROM
c 此表有712995条数据
LEFT JOIN u ON c.user_id = u.id
LEFT JOIN doc ON c.doctor_id = doc.id
LEFT JOIN s ON c.meal_id = s.id
WHERE
s.renew = 1
AND c.orderstatus = 1
AND c.endtime < UNIX_TIMESTAMP()
AND c.org_type = 'c'
AND u.is_doctor = 0
AND u.active = 1
AND doc.is_doctor IN (4, 5)
AND doc.is_family_doctor = 1
AND doc.active = 1
AND c.user_id NOT IN (
SELECT
user_id
FROM
d 此表有934455条数据
WHERE
d.log LIKE '%结束'
);
-- 执行时间为2.265s
优化后:
SET SESSION group_concat_max_len = 102400;
SELECT GROUP_CONCAT(user_id) FROM d WHERE d.log LIKE '%结束'; -- 执行了0.521s
SELECT
c.id
FROM
c
LEFT JOIN u ON c.user_id = u.id
LEFT JOIN doc ON c.doctor_id = doc.id
LEFT JOIN s ON c.meal_id = s.id
WHERE
s.renew = 1
AND c.orderstatus = 1
AND c.endtime < UNIX_TIMESTAMP()
AND c.org_type = 'c'
AND u.is_d = 0
AND u.active = 1
AND doc.is_d IN (4, 5)
AND doc.is_f_d = 1
AND doc.active = 1
AND c.user_id NOT IN (24986,24986,24986,24986,24986,24986,..............................................大概5千个id);
-- 执行时间1.579s
执行时间少了0.686s,但是GROUP_CONCAT(user_id)还执行了0.521s,所以总体时间没有什么差别(当前数量级),
而且后一个需要考虑字符串的大小问题。
目前就了解这些,以后有时间再细细琢磨。
MySQL IN和EXISTS的效率问题,以及执行优化的更多相关文章
- MySQL 子查询 EXISTS 和 NOT EXISTS(转)
MySQL EXISTS 和 NOT EXISTS 子查询 MySQL EXISTS 和 NOT EXISTS 子查询语法如下: SELECT ... FROM table WHERE EXISTS ...
- MySQL 子查询 EXISTS 和 NOT EXISTS
MySQL EXISTS 和 NOT EXISTS 子查询 MySQL EXISTS 和 NOT EXISTS 子查询语法如下: SELECT ... FROM table WHERE EXISTS ...
- mysql in与exists区别
1.exists是对外表做loop循环,每次loop循环再对内表(子查询)进行查询,那么因为对内表的查询使用的索引(内表效率高,故可用大表),而外表有多大都需要遍历,不可避免(尽量用小表),故内表大的 ...
- SQLSERVER语句 in和exists哪个效率高本人测试证明
SQLSERVR语句 in和exists哪个效率高本人测试证明 最近很多人讨论in和exists哪个效率高,今天就自己测试一下 我使用的是客户的数据库GPOSDB(已经有数据) 环境:SQLSERVE ...
- 关于in与exists的效率讨论
关于in与exists的效率讨论1).select * from A where id in (select id from B)以上查询使用了in语句,in只执行一次,他查出B表的所有id字段并缓存 ...
- Mysql 多表联合查询效率分析及优化
1. 多表连接类型 1. 笛卡尔积(交叉连接) 在MySQL中可以为CROSS JOIN或者省略CROSS即JOIN,或者使用',' 如: SELECT * FROM table1 CROSS JO ...
- in和exists的区别与SQL执行效率
in和exists的区别与SQL执行效率最近很多论坛又开始讨论in和exists的区别与SQL执行效率的问题,本文特整理一些in和exists的区别与SQL执行效率分析 SQL中in可以分为三类: 1 ...
- in和exists哪个效率高本人测试证明
in和exists哪个效率高本人测试证明 SQLSERVR语句 in和exists哪个效率高自己测试本人测试证明 最近很多人讨论in和exists哪个效率高,今天就自己测试一下 我使用的是客户的数据库 ...
- MySQL Execution Plan--NOT EXISTS子查询优化
在很多业务场景中,会使用NOT EXISTS语句来确保返回数据不存在于特定集合,部分场景下NOT EXISTS语句性能较差,网上甚至存在谣言"NOT EXISTS无法走索引". 首 ...
随机推荐
- 7kyu (难度系数kyu阶段数值越大难度越低) 数组分组及求和
几个人排成一排,分成两队.第一个人进入一队,第二个人进入第二队,第三个人进入第一队,以此类推. 给定一个正整数的数组(人的权重),返回两个整数的新数组/元组,其中第一个是第1组的总重量,第二个是第2组 ...
- LinkedList实现类
List还有一个LinkedList的实现,它是一个基于链表实现的List类,对于顺序访问集合中的元素进行了优化,特别是当插入.删除元素时速度非常快.因为LinkedList即实现了List接口,也实 ...
- thymeleaf常用属性
转 作者:ITPSC 出处:http://www.cnblogs.com/hjwublog/ th:action 定义后台控制器路径,类似<form>标签的action属性. 例如: ...
- Nginx配置安装(Mac)
我用到的安装工具是:homebrew 真的很方便! 步骤1: 打开终端,输入 brew info nginx结果:我们可以看到,nginx在本地还未安装(Not installed),nginx的来源 ...
- CountDownLatch实现多线程并发请求
package com.test; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Dat ...
- 9.源码分析---SOFARPC是如何实现故障剔除的?
SOFARPC源码解析系列: 1. 源码分析---SOFARPC可扩展的机制SPI 2. 源码分析---SOFARPC客户端服务引用 3. 源码分析---SOFARPC客户端服务调用 4. 源码分析- ...
- java并发编程(二十)----(JUC集合)CopyOnWriteArrayList介绍
这一节开始我们正式来介绍JUC集合类.我们按照List.Set.Map.Queue的顺序来进行介绍.这一节我们来看一下CopyOnWriteArrayList. CopyOnWriteArrayLis ...
- alluxio源码解析-netty部分(2)
netty简介 Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端. netty作为alluxio中重要的通讯组件 在常见的客户端上传,下载中,都会有n ...
- mysql优化---订单查询优化(1):视图优化+索引创建
订单的表结构采用了垂直分表的策略,将订单相关的不同模块的字段维护在不同表中 在订单处理这个页面,需要查询各种维度, 因此为了方便查询创建了v_sale_order视图(老版本) drop view v ...
- JQGrid之文件上传
文件/图片上传功能,简单总结如下 1.引入ajaxfileupload.js 注意:该文件需要在引入Jquery之后引入 下载链接:https://i.cnblogs.com/Files.aspx 2 ...