SQL关联查询直接连接和子查询的区别

  

运营组的同事最近提出一个需求,希望可以统计出用系统用户及订单情况,于是乎我们很想当然的写出了一个统计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关联查询直接连接和子查询的区别

  

进一步调整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关联查询直接连接和子查询的区别