运营组的同事最近提出一个需求,希望可以统计出用系统用户及订单情况,于是乎我们很想当然的写出了一个统计SQL,用户表用户和行程表直接加入,并且针对行程做了集团,但SQL执行速度出奇的慢。
<代码>解释选择用户。mobile_num, concat(用户。“姓”,users.“firstName”)作为用户名,users.“公司”, (案例“用户”。' idPhotoCheckStatus '然后' 2 ' '已认证’当‘3’’已驳回‘其他’待认证”)作为“idPhotoCheckStatus”结束, (案例“用户”。' driverLicenseCheckStatus '然后' 2 ' '已认证’当‘3’’已驳回‘其他’待认证”)作为“driverLicenseCheckStatus”结束, (案例“用户”。' companyCheckStatus '然后' 2 ' '已认证’当‘3’’已驳回‘其他’待认证”)作为“companyCheckStatus”结束, (案例“用户”。' unionCheckStatus '然后' 2 ' '已认证’当‘3’’已驳回‘其他’待认证”)作为“unionCheckStatus”结束, ptrip_num计数(passenger_trip.id) 从用户 离开加入passenger_trip alt=" SQL关联查询直接连接和子查询的区别">转而一想,10 w * 10 w,经过笛卡尔集之后,这不是百亿级的数据筛选吗? !于是换了一种写法进行尝试。
<代码>解释选择用户。mobile_num, concat(用户。“姓”,users.“firstName”)作为用户名,users.“公司”, (案例“用户”。' idPhotoCheckStatus '然后' 2 ' '已认证’当‘3’’已驳回‘其他’待认证”)作为“idPhotoCheckStatus”结束, (案例“用户”。' driverLicenseCheckStatus '然后' 2 ' '已认证’当‘3’’已驳回‘其他’待认证”)作为“driverLicenseCheckStatus”结束, (案例“用户”。' companyCheckStatus '然后' 2 ' '已认证’当‘3’’已驳回‘其他’待认证”)作为“companyCheckStatus”结束, (案例“用户”。' unionCheckStatus '然后' 2 ' '已认证’当‘3’’已驳回‘其他’待认证”)作为“unionCheckStatus”结束, (select count (passenger_trip.id)从passenger_trip passenger_trip的地方。用户id=用户。id和passenger_trip。地位!=ptrip_num '取消'), (select count (driver_trip.id)从driver_trip driver_trip的地方。用户id=用户。id和driver_trip。dtrip_num地位!='取消') 从用户 在公司!='本公司名”和公司!=肮娟浅啤?/代码>这样的效果居然比直接加入快了N倍,执行速度从未知到10秒内返回,查看执行计划:
进一步调整SQL进行尝试:
<代码>解释选择用户。mobile_num, concat(用户。“姓”,users.“firstName”)作为用户名,users.“公司”, (案例“用户”。' idPhotoCheckStatus '然后' 2 ' '已认证’当‘3’’已驳回‘其他’待认证”)作为“idPhotoCheckStatus”结束, (案例“用户”。' driverLicenseCheckStatus '然后' 2 ' '已认证’当‘3’’已驳回‘其他’待认证”)作为“driverLicenseCheckStatus”结束, (案例“用户”。' companyCheckStatus '然后' 2 ' '已认证’当‘3’’已驳回‘其他’待认证”)作为“companyCheckStatus”结束, (案例“用户”。' unionCheckStatus '然后' 2 ' '已认证’当‘3’’已驳回‘其他’待认证”)作为“unionCheckStatus”结束, ptrip_num, dtrip_num 从用户 左连接 (select count (passenger_trip.id) ptrip_num, passenger_trip。“标识”passenger_trip passenger_trip的地方。地位!='取消' passenger_trip集团。ptrip userId) alt=" SQL关联查询直接连接和子查询的区别">出现这种差别的原因,其实很简单,SQL语句执行的时候是有一定顺序的。
<李> <的> 强>先选择一个表,构成一个结果集。李> <李> <强>,强>对结果集进行筛选,筛选出需要的信息形成新的结果集。李> <李> <>强group by 强>对新的结果集分组。李> <李> <强>在强>筛选出想要的分组。李> <李> <强>选择强>选择列。李> <李> <>强按强>当所有的条件都弄完了。最后排序。李>
第一种写法,直接加入的结果,就是在100年亿条数据中进行筛选;
后面两种则是优先执行子查询,完成10 w级别的查询,再进行一次主表10 w级的关联查询,所以数量级明显少于第一种写法。SQL关联查询直接连接和子查询的区别