亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SQL關聯查詢 直接join 和子查詢的區別

發布時間:2020-07-21 17:22:43 來源:網絡 閱讀:7566 作者:layveen 欄目:MySQL數據庫

運營組的同事最近提出一個需求,希望可以統計出用系統用戶及訂單情況,于是乎我們很想當然的寫出了一個統計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_num
from users
left 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實現。

SQL關聯查詢  直接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_num
from users
where company != '本公司名' and company != '公司昵稱'

這樣的效果居然比直接join快了N倍,執行速度從未知到10秒內返回,查看執行計劃:

SQL關聯查詢  直接join 和子查詢的區別

進一步調整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_num
from 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.id
where company != '本公司名' and company != '公司昵稱'

居然5秒內返回,這才是正常的預期,10W級的數據篩選,應該是幾秒內返回的!

SQL關聯查詢  直接join 和子查詢的區別

出現這種差別的原因,其實很簡單,SQL語句執行的時候是有一定順序的。

  1. from 先選擇一個表,構成一個結果集。
  2. where 對結果集進行篩選,篩選出需要的信息形成新的結果集。
  3. group by 對新的結果集分組。
  4. having 篩選出想要的分組。
  5. select 選擇列。
  6. order by 當所有的條件都弄完了。最后排序。

第一種寫法,直接join的結果,就是在100億條數據中進行篩選;
后面兩種則是優先執行子查詢,完成10W級別的查詢,再進行一次主表10W級的關聯查詢,所以數量級明顯少于第一種寫法。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

湛江市| 桃园市| 滁州市| 腾冲县| 将乐县| 宁乡县| 曲阜市| 巧家县| 临颍县| 阳新县| 桦川县| 崇左市| 乌拉特中旗| 乐安县| 武山县| 保康县| 二连浩特市| 隆安县| 丹东市| 廊坊市| 平乐县| 宁陕县| 营口市| 西华县| 宜黄县| 云安县| 深水埗区| 通州区| 车致| 北宁市| 通渭县| 东乌| 岳普湖县| 阿勒泰市| 乌什县| 西贡区| 鄢陵县| 扬中市| 河北省| 东源县| 德令哈市|