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无法走索引". 首 ...
随机推荐
- 2019牛客暑期多校训练营(第四场)K.number
>传送门< 题意:给你一个字符串s,求出其中能整除300的子串个数(子串要求是连续的,允许前面有0) 思路: >动态规划 记f[i][j]为右端点满足mod 300 = j的子串个数 ...
- c++容器简单总结(续)
操作 效果 vector<T> c 产生空的vector vector<T> c1(c2) 产生同类型的c1,并将复制c2的所有元素 vector<T> c(n) ...
- CSS和html如何结合起来——选择符及优先级
1.选择符 兼容性 统配选择符 * 元素选择符 body 类选择符 .class id选择符 #id 包含原则符 p strong (所有 ...
- 基于高德开放平台的 NODE 天气信息组件
看看了画在手上的Armani手表,马上就快到了下班的时间了,心里总觉的空唠唠的, 好像空缺了什么一样,仔细的想了一想,微微叹了一口气,觉得是时候在这里和大家分享一下原因了........ 首先: ## ...
- Angular JS 中的服务注册方法
在Angular JS中创建服务的几种方法 factory() service() constant() value() provider() factory(name,fn(){}) 该服务为单例的 ...
- 二进制文件安装安装etcd
利用二进制文件安装安装etcd etcd组件作为一个高可用强一致性的服务发现存储仓库. etcd作为一个受到ZooKeeper与doozer启发而催生的项目,除了拥有与之类似的功能外,更专注于以下四点 ...
- middleware中间件
django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法. 在django项目的se ...
- 图解Redis之数据结构篇——压缩列表
前言 同整数集合一样压缩列表也不是基础数据结构,而是 Redis 自己设计的一种数据存储结构.它有点儿类似数组,通过一片连续的内存空间,来存储数据.不过,它跟数组不同的一点是,它允许存储的数据 ...
- python多线程与多进程及其区别
个人一直觉得对学习任何知识而言,概念是相当重要的.掌握了概念和原理,细节可以留给实践去推敲.掌握的关键在于理解,通过具体的实例和实际操作来感性的体会概念和原理可以起到很好的效果.本文通过一些具体的例子 ...
- 看完这篇还不清楚Netty的内存管理,那我就哭了!
说明 在学习Netty的时候,ByteBuf随处可见,但是如何高效分配ByteBuf还是很复杂的,Netty的池化内存分配这块还是比较难的,很多人学习过,看过但是还是云里雾里的,本篇文章就是主要来讲解 ...