在MySQL中,我们可以将NOT EXISTS语句转换为LEFT JOIN语句来进行优化,哪为什么会有性能提升呢?

使用NOT EXISTS方式SQL为:

SELECT count(1)FROMt_monitor mWHERE NOT exists(SELECT 1

FROM t_alarm_realtime ASaWHERE a.resource_id=m.resource_idAND a.resource_type=m.resource_typeAND a.monitor_name=m.monitor_name)

而使用LEFT JOIN方式SQL为:

SELECT count(1)FROMt_monitor mLEFT JOIN t_alarm_realtime ASaON a.resource_id=m.resource_idAND a.resource_type=m.resource_typeAND a.monitor_name=m.monitor_nameWHERE a.resource_id is NULL

从查询效果来看,NOT EXISTS 方式耗时29.38秒,而LEFT JOIN方式耗时1.20秒,性能提升25倍左右。

查看NOT EXISTS方式的执行计划:

*************************** 1. row ***************************id:1select_type:PRIMARY

table: m

partitions:NULLtype:indexpossible_keys:NULL

key: idx_id_name_type

key_len:119ref:NULLrows:578436filtered:100.00Extra: Usingwhere; Using index

*************************** 2. row ***************************id:2select_type: DEPENDENT SUBQUERYtable: a

partitions:NULLtype: eq_ref

possible_keys: idx_id_name_typekey: idx_id_name_type

key_len:119ref: cmdb.m.resource_id,cmdb.m.monitor_name,cmdb.m.resource_type

rows:1filtered:100.00Extra: Usingindex

查看LEFT JOIN方式的执行计划:

*************************** 1. row ***************************id:1select_type: SIMPLEtable: m

partitions:NULLtype:indexpossible_keys:NULL

key: idx_id_name_type

key_len:119ref:NULLrows:578436filtered:100.00Extra: Usingindex

*************************** 2. row ***************************id:1select_type: SIMPLEtable: a

partitions:NULLtype: eq_ref

possible_keys: idx_id_name_typekey: idx_id_name_type

key_len:119ref: cmdb.m.resource_id,cmdb.m.monitor_name,cmdb.m.resource_type

rows:1filtered:100.00Extra: Usingwhere; Not exists; Using index

使用SQL PROFILE查看NOT EXISTS 执行过程:

+--------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+

| Status | Duration | CPU_user | CPU_system | Context_voluntary | Context_involuntary | Block_ops_in | Block_ops_out |

+--------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000022 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000028 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000022 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000029 | 0.001000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000022 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000027 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000028 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000026 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000025 | 0.000000 | 0.000999 | 0 | 0 | 0 | 0 |

| Sending data | 0.000031 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000028 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000027 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000027 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000027 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000027 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000027 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000027 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000027 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000028 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000027 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000027 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000022 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000027 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000027 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 0.000033 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| end | 0.000024 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| query end | 0.000028 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| closing tables | 0.000027 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| freeing items | 0.000039 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| logging slow query | 0.000059 | 0.000000 | 0.000000 | 0 | 0 | 0 | 16 |

| cleaning up | 0.000033 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

+--------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+

使用SQL PROFILE查看LEFT JOIN 执行过程:

+----------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+

| Status | Duration | CPU_user | CPU_system | Context_voluntary | Context_involuntary | Block_ops_in | Block_ops_out |

+----------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+

| starting | 0.000162 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| checking permissions | 0.000025 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| checking permissions | 0.000025 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Opening tables | 0.000033 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| init | 0.000049 | 0.001000 | 0.000000 | 0 | 0 | 0 | 0 |

| System lock | 0.000030 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| optimizing | 0.000033 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| statistics | 0.000050 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| preparing | 0.000037 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| executing | 0.000025 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| Sending data | 1.200899 | 1.547764 | 0.124981 | 7460 | 116 | 0 | 8608 |

| end | 0.000103 | 0.000000 | 0.000000 | 2 | 0 | 0 | 0 |

| query end | 0.000028 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| closing tables | 0.000028 | 0.000000 | 0.000000 | 0 | 0 | 0 | 0 |

| freeing items | 0.000039 | 0.000000 | 0.000000 | 2 | 0 | 0 | 8 |

| logging slow query | 0.000052 | 0.000000 | 0.000000 | 0 | 0 | 0 | 24 |

| cleaning up | 0.000030 | 0.000000 | 0.000000 | 1 | 0 | 0 | 0 |

+----------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+

两种执行方式对比:

1、从执行计划来看,两个表都使用了索引,区别在于NOT EXISTS使用“DEPENDENT SUBQUERY”方式,而LEFT JOIN使用普通表关联的方式

2、从执行过程来看,LEFT JOIN方式主要消耗Sending data的上,在NOT EXISTS方式主要消耗在"executing"和“Sending data”两项上,受限于PROFILE只能记录100行结果,因此超过57万个"executing"和“Sending data”的组合项没有显示,虽然每次"executing"和“Sending data”的组合项消耗时间较少(约50毫秒),但由于执行次数较高,导致最终执行时间较长(50μs*578436=28921800us=28.92s)

如何在NOT EXISTS和LEFT JOIN中选择:

1、当外层数据较少时,子查询循环次数较少,使用NOT EXISTS并不会导致严重的性能问题,推荐使用NOT EXISTS方式。

2、当外层数据较大时,子查询消耗随外层数据量递增,查询性能较差,推荐使用LEFT JOIN方式

总结:

按照存在即合理是客观唯心主义的理论,NOT EXISTS以更直观地方式实现业务需求,在SQL复杂度上要远低于LEFT JOIN,且在生产执行计划时,NOT EXISTS方式相对更稳定些,LEFT JOIN可能会随统计信息变化而生产不同的执行计划。

mysql not exists优化_MySQL优化--NOT EXISTS和LEFT JOIN方式差异相关推荐

  1. mysql字段优化_MySQL优化(1):字段的设计

    Web项目中,当Java或者Go等语言速度提升到瓶颈的时候,我们需要关心MySQL的优化 可以优化的方面有很多:设计表.负载均衡.读写分离.SQL语句优化等 (1)IP地址设计 例如我们需要存储IP地 ...

  2. mysql分页查询关键_MySQL优化教程之超大分页查询

    背景 基本上只要是做后台开发,都会接触到分页这个需求或者功能吧.基本上大家都是会用MySQL的LIMIT来处理,而且我现在负责的项目也是这样写的.但是一旦数据量起来了,其实LIMIT的效率会极其的低, ...

  3. 有关mysql的清理与优化_mysql优化点整理

    优化sql一般步骤: 1.通过show (session 或者 global) status 来查看( 当前连接 或者 数据库上次开机以来 )的服务器状态信息,默认是session 例如: show ...

  4. mysql的exists解析_mysql中关于exists的深入讲解

    mysql中关于exists的讲解 我认为exists语法是mysql中一个很强大的工具,可以简单地实现某些复杂的数据处理. 下面我谈谈与exists有关的三个方面. all 与 any 首先,看到了 ...

  5. mysql 批量加索引_mysql优化:按期删数据 + 批量insert + 字符串加索引为何很傻

    嗯,犯了一个很低级的错误,最近暴露出来了.html 背景:mysql 1. 内部平台,接口间断性无返回,查询日志注意到失败时,接口耗时达到4000+(正常状态:100+ms)git 2. 增长日志打点 ...

  6. mysql in 命中索引_MySql优化-你的SQL命中索引了吗

    在项目开发中SQL是必不可少的,表索也一样.这些SQL的运行性能不知道吗?有多少是命中了索引的?命中哪个索引?索引中有哪个是无效索引?这些无效索引是否会影响系统的性能?带着这些问题我们一起来学习一下. ...

  7. mysql执行计划重用_MySQL 优化之EXPLAN执行计划

    MySQL优化之EXPLAN执行计划 ** 备注 ** 本文改编自https://www.processon.com/view/5d4fe8f4e4b04399f5a0303e?fromnew=1#m ...

  8. mysql防止索引崩溃_MySQL优化之避免索引失效的方法

    在上一篇文章中,通过分析执行计划的字段说明,大体说了一下索引优化过程中的一些注意点,那么如何才能避免索引失效呢?本篇文章将来讨论这个问题. 避免索引失效的常见方法 1.对于复合索引的使用,应按照索引建 ...

  9. mysql+index组合索引_MySQL 优化之 index merge(索引合并)

    标签: MySQL5.0之前,一条语句中一个表只能使用一个索引,无法同时使用多个索引.但是从5.1开始,引入了 index merge 优化技术,对同一个表可以使用多个索引.理解了 index mer ...

最新文章

  1. latex不能识别eps图片
  2. 不是语言之争---Go vs Erlang
  3. 用Python爬网页需要了解什么背景知识
  4. 判断访问接口的设备是安卓还是ios
  5. thinkphp项目mysql类关系_ThinkPHP数据库与模型
  6. php-fpm 进程在云服务器cpu分配不均匀
  7. android widget 发送广播,android-从应用程序向小部件发送数据
  8. thymealf如何实现传单个变量给html_50个关于IPython的奇技淫巧
  9. opencv各种小程序代码
  10. 让你相见恨晚的Photoshop 技巧
  11. Word2vec代码实现
  12. 使用Heartbeat实现双机热备
  13. SAP中导出电子表格问题处理案例
  14. python调整图片色相,对应ps的色相值
  15. Windows mobile 客户解决方案成功案例
  16. 宋朝记载的超新星爆发和光速不变
  17. WINCC组态软件Basic/Comfort/Advanced/Professional版本
  18. .me 域名注册的方法和规则
  19. 数据库安装【MySQL 2059错误和oracle11g INS-3001】
  20. 强烈推荐:web前端目前最受欢迎的4款编辑器

热门文章

  1. python二维平面上依次得到(0,0)距离相等的点(x,y)坐标,并打印距离
  2. mysql垃圾清理_mysql 垃圾图片清理
  3. mysql 定期备份_MySQL定时备份(全量备份+增量备份)
  4. vs2019编译c语言提示有病毒,关于VS2019代码编译的问题(C++)
  5. java滑动窗体动画_java – 为布局滑入和滑出动画
  6. 题解-bzoj3901 棋盘游戏
  7. Redis主从读写分离配置
  8. jmeter压测前清理内存
  9. Android群英传笔记——摘要,概述,新的出发点,温故而知新,能够为师矣!
  10. 【古典入门】巴洛克音乐家-斯卡拉蒂