当前位置: 首页 > news >正文

MySql的in和join对比谁更高效

公司有个SQl根据时间判断是否变化进而更新到主表通知下游服务告知变化

首先看下优化前和优化后的sql:

优化前:执行很慢

UPDATE vrs_video 
SET updated_at = now() 
WHERE
	vrs_video.id IN (
	SELECT DISTINCT
		video_id 
	FROM
		vrs_play_source 
	WHERE
	vrs_play_source.updated_at > DATE_ADD( NOW(), INTERVAL - 5 MINUTE ))

优化后:速度很快

UPDATE vrs_video v
INNER JOIN (
	SELECT DISTINCT
		video_id 
	FROM
		vrs_play_source 
	WHERE
	vrs_play_source.updated_at > DATE_ADD( NOW(), INTERVAL - 5 MINUTE )) AS subquery ON v.id = subquery.video_id 
	SET v.updated_at = NOW()

说明:vrs_video是视频表、vrs_play_source 是播放源表 如果播放源表变化那就更新到 视频表中,最后通过查询 视频表的变化 通知下游

实际上业务比这个复杂不止这一个sql,一个视频 他有剧集表、分类表、人物表、标签表等。需要把每个副表的变化都更新到主表,然后主表拿到更新的视频ID去通知下游。

执行顺序比较

优化前的SQL:

我们看下他的执行计划

执行顺序:

  • 扫描主表
    首先,数据库引擎扫描 vrs_video 表。根据执行计划,它使用了 PRIMARY 索引,可能会遍历大量行(计划中显示约 5702245 行)。

  • 执行依赖子查询
    对于 vrs_video 表中的每一行,都会对子查询

    select distinct video_id from vrs_play_source where vrs_play_source.updated_at > DATE_ADD(NOW(),INTERVAL -5 MINUTE)

    进行求值。执行计划中显示该子查询为 “DEPENDENT SUBQUERY”,这意味着它与外层查询有关联(尽管查询本身没有引用外层字段,但 MySQL 优化器可能判定其依赖性),可能在每行判断时重复计算或部分重复计算。

  • 条件判断与更新
    如果当前 vrs_video.id 在子查询返回的 video_id 集合中,则满足条件,接着执行更新操作,将 updated_at 字段设置为 NOW()

优化后的SQl执行顺序

  • 构造派生表(子查询)
    首先,执行派生子查询

    select distinct video_id from vrs_play_source where vrs_play_source.updated_at > DATE_ADD(NOW(),INTERVAL -5 MINUTE)

    该子查询的结果会被物化成一个临时表(或称派生表),通常数据量较小(如执行计划显示只有几行)。

  • JOIN 连接
    使用派生表与 vrs_video 表进行内连接,连接条件为 v.id = subquery.video_id。由于 vrs_video 表的主键索引被利用(执行计划中显示为 eq_ref),连接过程非常高效。

  • 更新操作
    对于连接成功的记录,直接更新 vrs_video 表中的 updated_at 字段为 NOW()

总结

  • 第一个 SQL:
    执行顺序为先扫描 vrs_video 表,然后对每一行执行依赖子查询进行判断,最后更新满足条件的记录。由于子查询被标记为“DEPENDENT”,可能会在外层每行判断时多次执行,从而影响效率。

  • 第二个 SQL:
    执行顺序是先独立执行子查询,将满足条件的 video_id 物化为一个临时表,再将该结果与 vrs_video 表进行高效的索引连接,最后更新匹配的记录。整体流程较清晰,且子查询只执行一次。

这种执行顺序的差异是性能差异的重要原因之一,尤其是在数据量较大的情况下,第二种写法往往会更高效。

相关文章:

  • JVM_八股场景题
  • 【含文档+PPT+源码】Python爬虫人口老龄化大数据分析平台的设计与实现
  • Kubernetes开发环境minikube | 开发部署apache tomcat web集群应用
  • VUE2脚手架的下载与安装
  • 【含文档+PPT+源码】基于Python爬虫二手房价格预测与可视化系统的设计与实现
  • php虚拟站点提示No input file specified时的问题及权限处理方法
  • Web3 的隐私保护机制:如何保障个人数据安全
  • 【今日EDA行业分析】2025年3月8日
  • http协议的三次握手机制
  • Spring源码探析(一):SpringApplication构造函数核心逻辑
  • 工程化与框架系列(27)--前端音视频处理
  • 用OpenCV写个视频播放器可还行?(C++版)
  • MySQL知识点(第一部分)
  • 深度学习|自监督学习新星:DINO 解析与实践指南
  • 请谈谈 HTTP 中的安全策略,如何防范常见的Web攻击(如XSS、CSRF)?
  • 机器人匹诺曹机制,真话假话平衡机制
  • rpc和proto
  • C++ 算法竞赛STL以及常见模板
  • VMware workstation Pro 17 官网下载教程/安装包
  • 百货店的诞生与现代商业革命:结合开源AI智能客服、AI智能名片与S2B2C商城小程序的新视角
  • 韧性十足的中国外贸企业:“不倒翁”被摁下去,还会再弹起来
  • 娃哈哈:调整产销布局致部分工厂停工,布局新产线可实现自主生产,不排除推新品牌
  • 30平米的无障碍酒吧里,我们将偏见折叠又摊开
  • 普京确定俄乌谈判俄方代表团名单
  • 4月份全国企业销售收入同比增长4.3%
  • 泽连斯基:将带领乌代表团前往土耳其,已准备好与普京会谈