网上可以查到很多这样的说法:

如果查询的两个表大小相当,那么用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的效率问题,以及执行优化的更多相关文章

  1. MySQL 子查询 EXISTS 和 NOT EXISTS(转)

    MySQL EXISTS 和 NOT EXISTS 子查询 MySQL EXISTS 和 NOT EXISTS 子查询语法如下: SELECT ... FROM table WHERE EXISTS ...

  2. MySQL 子查询 EXISTS 和 NOT EXISTS

    MySQL EXISTS 和 NOT EXISTS 子查询 MySQL EXISTS 和 NOT EXISTS 子查询语法如下: SELECT ... FROM table WHERE EXISTS ...

  3. mysql in与exists区别

    1.exists是对外表做loop循环,每次loop循环再对内表(子查询)进行查询,那么因为对内表的查询使用的索引(内表效率高,故可用大表),而外表有多大都需要遍历,不可避免(尽量用小表),故内表大的 ...

  4. SQLSERVER语句 in和exists哪个效率高本人测试证明

    SQLSERVR语句 in和exists哪个效率高本人测试证明 最近很多人讨论in和exists哪个效率高,今天就自己测试一下 我使用的是客户的数据库GPOSDB(已经有数据) 环境:SQLSERVE ...

  5. 关于in与exists的效率讨论

    关于in与exists的效率讨论1).select * from A where id in (select id from B)以上查询使用了in语句,in只执行一次,他查出B表的所有id字段并缓存 ...

  6. Mysql 多表联合查询效率分析及优化

    1. 多表连接类型 1. 笛卡尔积(交叉连接) 在MySQL中可以为CROSS JOIN或者省略CROSS即JOIN,或者使用','  如: SELECT * FROM table1 CROSS JO ...

  7. in和exists的区别与SQL执行效率

    in和exists的区别与SQL执行效率最近很多论坛又开始讨论in和exists的区别与SQL执行效率的问题,本文特整理一些in和exists的区别与SQL执行效率分析 SQL中in可以分为三类: 1 ...

  8. in和exists哪个效率高本人测试证明

    in和exists哪个效率高本人测试证明 SQLSERVR语句 in和exists哪个效率高自己测试本人测试证明 最近很多人讨论in和exists哪个效率高,今天就自己测试一下 我使用的是客户的数据库 ...

  9. MySQL Execution Plan--NOT EXISTS子查询优化

    在很多业务场景中,会使用NOT EXISTS语句来确保返回数据不存在于特定集合,部分场景下NOT EXISTS语句性能较差,网上甚至存在谣言"NOT EXISTS无法走索引". 首 ...

随机推荐

  1. 一个完整的产品设计流程——家庭安全管家

    不管是产品设计,还是前后端开发,始终都应该做出来才能够有很好的提高锻炼.书看得再多,如果不配合实际练习始终得不到实质性的进展. 接下来的案例是和几位学弟学妹一起做的,契机是参加一个用户体验设计比赛,从 ...

  2. RocketMQ中Producer消息的发送

    上篇博客介绍过Producer的启动,这里涉及到相关内容就不再累赘了 [RocketMQ中Producer的启动源码分析] Producer发送消息,首先需要生成Message实例: public c ...

  3. Java悲观锁Pessimistic-Lock常用实现场景

    1:商品库存秒杀采用悲观锁Pessimistic-Lock主要好处是安全,充分利用了数据库的性能来做的一种锁机制. 悲观锁的实现: (1)环境:mysql + jdbctemplate (2)商品表g ...

  4. java8(1)--- lambda

    项目马上切java8了,之前对于java8的东西都是东打一棒西打一锤的了解了些.这次搜集整理了下,从lambda到stream相关的API等. 1.Lambda和匿名内部类 Lambda 是一个匿名的 ...

  5. vscode c 语言 win10

    在看 CSAPP 一些课程,一些c 语言的小程序的例子,想跑起来试试,用一个DEV  c++  简单上手,但这是一个上古的IDE, 前端开发中的代码不全,语法高亮,都不太好,就想着为什么不折腾一下 V ...

  6. gRPC【RPC自定义http2.0协议传输】

    gRPC 简介 gRPC是由Google公司开源的高性能RPC框架. gRPC支持多语言 gRPC原生使用C.Java.Go进行了三种实现,而C语言实现的版本进行封装后又支持C++.C#.Node.O ...

  7. 讲解开源项目:5分钟搭建私人Java博客系统

    本文适合刚学习完 Java 语言基础的人群,跟着本文可了解和运行 Tale 项目.示例均在 Windows 操作系统下演示 本文作者:HelloGitHub-秦人 HelloGitHub 推出的< ...

  8. 用 程序 解决 windows防火墙 的 弹窗 问题

    今天用户反馈了一个问题,运行程序弹了个框 这个只有程序第一次运行会出来,之后就不会了. 当然改个程序名字,又会弹出来. 强烈怀疑是写到了注册表,果然被我找到了. “HKEY_LOCAL_MACHINE ...

  9. JDK基础必备面试十问

    1. new一个对象在Java内部做了哪些工作? 从静态角度来看,new一个对象表示创建一个类的对象实例. 从JVM运行角度来看,当JVM执行到new字节码时,首先会去查看类有没有被加载到内存以及初始 ...

  10. python代码规范整理

    规范参考源: 1.pep8(python代码样式规范):中文文档      https://blog.csdn.net/ratsniper/article/details/78954852 2.pep ...