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无法走索引". 首 ...
随机推荐
- SSM - Mybatis SQL映射文件
MyBatis 真正的力量是在映射语句中.和对等功能的jdbc来比价,映射文件节省很多的代码量.MyBatis的构建就是聚焦于sql的. sql映射文件有如下几个顶级元素:(按顺序) cache配置给 ...
- RobotFramework_3.SeleniumLibrary操作(一)
RobotFramework_3.SeleniumLibrary操作(一) *:first-child { margin-top: 0 !important; } body>*:last-chi ...
- codeforces 340 A. The Wall
水水的一道题,只需要找xy的最小公倍数,然后找a b区间有多少个可以被xy的最小公倍数整除的数,就是答案. //============================================ ...
- WIN10安装VC6.0无法使用的解决办法
WIN10安装VC6.0无法使用的解决办法 VC6.0确实已经太老了 VC6.0实在是很久以前的开发工具了,现在的win10已经对该软件不兼容,但是为了能使抱着怀旧情节的初学者们能像教科书或老前辈们一 ...
- Mac环境下升级gcc版本--rocksdb
前言 在mac环境下编译rocksdb,需要配置依赖的编译环境,其中有一项比较麻烦:c++编译要支持C++11,但是在mac环境安装xcode-select --install之后,已经安装有了gcc ...
- memCached的配置文件 配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- Tomcat发布War包或者Maven项目
在tomcat的conf目录下面的server.xml中修改如下: Host name="localhost" appBase="webapps" unpac ...
- 搭建nexus私服
一.安装 1.从网上下载nexus软件https://www.sonatype.com/download-oss-sonatype 下载Nexus Repository Manager OSS软件包 ...
- Power Designer导出模型的sql加注释-Oracle语句
第一步:Database-->Edit Current DBMS 第二步: 然后分别将 Script-->Objects-->Table-->TableComment Scri ...
- 控制台基于Quartz.Net组件实现定时任务调度(一)
前言: 你曾经需要应用执行一个任务吗?比如现在有一个需求,需要每天在零点定时执行一些操作,那应该怎样操作呢? 这个时候,如果你和你的团队是用.NET编程的话,可以考虑使用Quartz.NET调度器.允 ...