SQL关联查询 直接join 和子查询的区别
发表于:2025-01-21 作者:千家信息网编辑
千家信息网最后更新 2025年01月21日,运营组的同事最近提出一个需求,希望可以统计出用系统用户及订单情况,于是乎我们很想当然的写出了一个统计SQL,用户表user和行程表直接join,并且针对行程做了group,但SQL执行速度出奇的慢。e
千家信息网最后更新 2025年01月21日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安全错误
数据库的锁怎样保障安全
如何更换服务器坏硬盘
抽水服务器是什么原因
互联网服务行业和网络科技
徐汇区品牌软件开发诚信为本
数据库系统及应用答案
共建网络安全议论文800字
挂抖店的服务器
数据库运维自动化平台开源
云霄县萍茂网络技术工作室
服务器地址和ip
黑魂3服务器登入不了能玩吗
软件开发与系统工程哪个好
java显示数据库的图书信息
网络安全法定期开展测评
轮回服服务器预注册
农业方面的软件开发公司
万兆 服务器
网络安全宣传周为9月第几周
数据库能存多少数字
网络安全领导小组成员单位
装配式网络技术维修
渗透网络安全技巧
域域用户服务器管理员权限
成都云上软件开发公司
软件开发人时报价
服务器 指纹
数据库建表命令是什么
南开网络安全攻防基础期末
河北回收服务器主板
武汉大学网络安全学院介绍