SQL join和EXISTS效率

先看两个查询,查询目的是在a表中找出b表出现的vid

1.join查询

sql 复制代码
select a.vid, a.attach_url, a.attach_url_type, a.create_time
from ods_truck.tl_vehicle_attach_log a
         join (select distinct vid
               from ods_truck.tl_truck_log_20240613
               where oprater in ('remove', 'delete')
                 and cast(oprater_time as bigint) < unix_timestamp('20210101', 'yyyyMMdd') * 1000
) b on a.vid = b.vid;

2.exists查询

sql 复制代码
select a.vid, a.attach_url, a.attach_url_type, a.create_time
from ods_truck.tl_vehicle_attach_log a
where exists (
    select 1
    from ods_truck.tl_truck_log_20240613 b
    where a.vid = b.vid
      and oprater in ('remove', 'delete')
      and cast(oprater_time as bigint) < unix_timestamp('20210101', 'yyyyMMdd') * 1000
    )
exists 解释

exists 和 not exists 用于判断B表结果集是否在A表存在,这个使用select 1原因是exists 不需要判断具体的列,只需要知道有没有结果集返回

  • exists 有结果集返回为真
  • not exists 没有结果集返回为真

这里使用select 1没有查询所有的列,优化了查询效率

比较效率

第一种join

  • 优点:子查询先执行,只保留了满足条件的vid的去重集合,减少了主查询时需要比较的记录数,如果vid上有索引,可能会更高效。
  • 缺点:如果子查询返回大量不同的vid,则JOIN操作可能消耗较多资源

第二个查询(EXISTS方式)

  • 优点:EXISTS通常在找到第一个匹配项后就会停止后续的行搜索,因此对于外层表的每一行,内层查询不会全表扫描,这在内层表数据量大时非常高效。
  • 缺点:对于每个外层表的行,都需要执行一次内层查询,如果外层表非常大,这可能会导致较高的查询成本

总结

一般而言,如果内层查询(即满足特定条件的vid)返回的结果集较小,且外层表较大,EXISTS可能会更高效 ,因为它避免了不必要的全表扫描。相反,如果内层查询返回的结果集相对较大,而外层表较小,预先计算并JOIN去重结果集的方法可能会更优

实际效率还需根据具体的数据库系统优化器、索引策略、数据分布等因素来确定,建议在实际环境中进行性能测试来决定最佳方案。

相关推荐
鸽芷咕1 小时前
MySQL/PostgreSQL 迁移金仓 KES:LEFT JOIN 丢数据排查与避坑指南
数据库·mysql·postgresql
2301_777998348 小时前
Linux信号机制
linux
Csvn10 小时前
📊 SQL 入门 Day 7:子查询 — 查询中的查询
后端·sql
一叶龙洲10 小时前
win11与Ubuntu之间同步配置、插件
linux·运维·ubuntu
CHANG_THE_WORLD11 小时前
12.总结:深入理解 Linux I/O 多路复用:select、poll、epoll 全解析
linux·运维·服务器
2401_8414956411 小时前
【数据结构】B+树
数据结构·数据库·c++·b+树·概念·结构·操作原理
风曦Kisaki11 小时前
# Linux笔记:操作系统优化与资源管理
linux·运维·服务器·笔记
Mr.HeBoYan12 小时前
一次持续三天才出现的丢包故障——深入解析 DPDK Memory Ordering、rte_ring 与 CPU Memory Barrier (下)
linux·网络·算法·架构·dpdk
Hardworking66613 小时前
第7章 软硬件系统集成
数据库·软硬件系统集成
名字还没想好☜13 小时前
Go 的 time.Ticker 陷阱:定时任务里被忽略的内存泄漏与正确关闭
java·数据库·golang·go·定时器