当前位置: 首页 > 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 表进行高效的索引连接,最后更新匹配的记录。整体流程较清晰,且子查询只执行一次。

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

http://www.dtcms.com/a/59674.html

相关文章:

  • 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商城小程序的新视角
  • [网络爬虫] 动态网页抓取 — Selenium 元素定位
  • 虚幻基础:动画层接口
  • tcp udp区别
  • 【英伟达AI论文】多模态大型语言模型的高效长视频理解
  • STM32 内置的通讯协议
  • 如何监控 Pod 的 CPU/内存使用率,prometheus+grafana
  • Linux内核学习(一)——Vmware虚拟机安装Ubuntu20.4系统及QEMU模拟ARM64 Linux
  • 使用 Python 将 PDF 转换为文本:打造一个简单高效的提取工具
  • 行业案例:10Wtps超高并发“某节跳动”钱包架构与落地方案
  • 【论文精读】GaussReg: Fast 3D Registration with Gaussian Splatting