SQL关联查询 直接join 和子查询的区别
发表于:2025-11-13 作者:千家信息网编辑
千家信息网最后更新 2025年11月13日,运营组的同事最近提出一个需求,希望可以统计出用系统用户及订单情况,于是乎我们很想当然的写出了一个统计SQL,用户表user和行程表直接join,并且针对行程做了group,但SQL执行速度出奇的慢。e
千家信息网最后更新 2025年11月13日SQL关联查询 直接join 和子查询的区别
运营组的同事最近提出一个需求,希望可以统计出用系统用户及订单情况,于是乎我们很想当然的写出了一个统计SQL,用户表user和行程表直接join,并且针对行程做了group,但SQL执行速度出奇的慢。
explain select users.`mobile_num`, concat(users.`lastName` ,users.`firstName`) as userName, users.`company`, (case `users`.`idPhotoCheckStatus` when '2' then '已认证' when '3' then '已驳回' else '待认证' end) as `idPhotoCheckStatus`, (case `users`.`driverLicenseCheckStatus` when '2' then '已认证' when '3' then '已驳回' else '待认证' end) as `driverLicenseCheckStatus`, (case `users`.`companyCheckStatus` when '2' then '已认证' when '3' then '已驳回' else '待认证' end) as `companyCheckStatus`, (case `users`.`unionCheckStatus` when '2' then '已认证' when '3' then '已驳回' else '待认证' end) as `unionCheckStatus`, count(passenger_trip.id) as ptrip_numfrom usersleft join passenger_trip on passenger_trip.userId = users.id and passenger_trip.status != 'cancel'left join driver_trip on driver_trip.`userId`=users.`id` and driver_trip.`status` != 'cancel'where company != '本公司名' and company != '本公司昵称'当时的第一反应是数据库挂住了,因为用户表的数据量10W左右,行程表的数据也是10W左右,不可能这么慢!通过explain查看分析计划,并且查看过关联字段的索引情况,发现这是一个最常见的关联查询,当然是通过join实现。
转而一想,10W*10W,经过笛卡尔集之后,这不是百亿级的数据筛选吗?!于是换了一种写法进行尝试。
explain select users.`mobile_num`, concat(users.`lastName` ,users.`firstName`) as userName, users.`company`, (case `users`.`idPhotoCheckStatus` when '2' then '已认证' when '3' then '已驳回' else '待认证' end) as `idPhotoCheckStatus`, (case `users`.`driverLicenseCheckStatus` when '2' then '已认证' when '3' then '已驳回' else '待认证' end) as `driverLicenseCheckStatus`, (case `users`.`companyCheckStatus` when '2' then '已认证' when '3' then '已驳回' else '待认证' end) as `companyCheckStatus`, (case `users`.`unionCheckStatus` when '2' then '已认证' when '3' then '已驳回' else '待认证' end) as `unionCheckStatus`, (select count(passenger_trip.id) from passenger_trip where passenger_trip.userId = users.id and passenger_trip.status != 'cancel') as ptrip_num, (select count(driver_trip.id) from driver_trip where driver_trip.userId = users.id and driver_trip.status != 'cancel') as dtrip_numfrom userswhere company != '本公司名' and company != '公司昵称'这样的效果居然比直接join快了N倍,执行速度从未知到10秒内返回,查看执行计划:
进一步调整SQL进行尝试:
explain select users.`mobile_num`, concat(users.`lastName` ,users.`firstName`) as userName, users.`company`, (case `users`.`idPhotoCheckStatus` when '2' then '已认证' when '3' then '已驳回' else '待认证' end) as `idPhotoCheckStatus`, (case `users`.`driverLicenseCheckStatus` when '2' then '已认证' when '3' then '已驳回' else '待认证' end) as `driverLicenseCheckStatus`, (case `users`.`companyCheckStatus` when '2' then '已认证' when '3' then '已驳回' else '待认证' end) as `companyCheckStatus`, (case `users`.`unionCheckStatus` when '2' then '已认证' when '3' then '已驳回' else '待认证' end) as `unionCheckStatus`, ptrip_num, dtrip_numfrom users left join (select count(passenger_trip.id) as ptrip_num, passenger_trip.`userId` from passenger_trip where passenger_trip.status != 'cancel' group by passenger_trip.`userId` ) as ptrip on ptrip.userId = users.id left join (select count(driver_trip.id) as dtrip_num, driver_trip.`userId` from driver_trip where driver_trip.status != 'cancel' group by driver_trip.`userId` ) as dtrip on dtrip.userId = users.idwhere company != '本公司名' and company != '公司昵称'居然5秒内返回,这才是正常的预期,10W级的数据筛选,应该是几秒内返回的!
出现这种差别的原因,其实很简单,SQL语句执行的时候是有一定顺序的。
- from 先选择一个表,构成一个结果集。
- where 对结果集进行筛选,筛选出需要的信息形成新的结果集。
- group by 对新的结果集分组。
- having 筛选出想要的分组。
- select 选择列。
- order by 当所有的条件都弄完了。最后排序。
第一种写法,直接join的结果,就是在100亿条数据中进行筛选;
后面两种则是优先执行子查询,完成10W级别的查询,再进行一次主表10W级的关联查询,所以数量级明显少于第一种写法。
认证
公司
数据
结果
查询
关联
写法
昵称
用户
行程
情况
行程表
选出
速度
用户表
分组
尝试
统计
选择
出奇
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
比特币服务器是谁运行的
数据库技术的必要性和重要性
uniapp 数据库操作
建立数据库表格的代码
数据库rs
辽宁运营网络技术服务怎么样
日本科技互联网怎么样
数据库还能用吗
数据库表中城市的数据类型是什么
服务器直接插硬盘能识别吗
百得思维软件开发应届生待遇
锋宇网络技术有限公司
视频服务器可以控制球机吗
数据库凭白无故要密码
股票兼职软件开发
网络安全技术提取祛斑
内江安卓软件开发公司
淘宝上卖的服务器
盛天网络技术有限公司
互联网公司的科技股
腾讯云服务器备案
郧阳区正规软件开发统计
做一台小型服务器
vc 适合软件开发吗
上海中友通信网络技术
网络技术发展3条主线
若有高校教学数据库
国际服匹配不到服务器为什么
网络安全学习
大数据和网络安全哪个方向