鍍金池/ 問答/數(shù)據(jù)庫  網(wǎng)絡安全/ 關于left join 底層算法的困惑

關于left join 底層算法的困惑

有個SQL的問題咨詢下:
關于PostgreSQL 或者 MySQL的left join 實現(xiàn)

假設:表結構

table_name :user
uid    name
1      張三
2      李四
3      王五

table_name : age
uid    age
1      10
2      20
3      30
4      40
SQL如下:

示例1:
SELECT t1.user,t2.age
FROM user t1
LEFT JOIN age t2 ON t1.uid=t2.uid

示例2:
SELECT t1.user
       ,(SELECT age FROM age WHERE uid=t1.uid) as age
FROM user t1

結果:示例2的查詢時間優(yōu)于示例1,為什么........unbelievable

懷疑點:

示例1的SQL執(zhí)行順序是否是:
    第一種:
    1. 查詢user全表
    2. 查詢age全表
    3. 算法引擎將兩種數(shù)據(jù)進行逐個匹配,獲取結果

    第二種:
    1. 查詢user全表
    2. 根據(jù)user查詢出的數(shù)據(jù)為查詢條件,查詢age表
    3. 算法引擎將兩種數(shù)據(jù)進行逐個匹配,獲取結果

是哪一種??

望解惑~

補充:

    上面表是假設的,實際表有些復雜,但是邏輯是這個樣子….
    
    總結一下問題:
    
    SQL中可能基礎數(shù)據(jù)(主表數(shù)據(jù))就10條,但是關聯(lián)表中的數(shù)據(jù)可能百萬條(與這10條相關的就幾十萬條),
    是查詢百萬條數(shù)據(jù)匹配,還是查詢幾十萬條匹配
回答
編輯回答
款爺

left join 的執(zhí)行過程:
1.FROM:對左右兩張表執(zhí)行笛卡爾積,產生第一張表vt1(臨時表)。行數(shù)為n*m(n為左表的行數(shù),m為右表的行數(shù)
2.ON:根據(jù)ON的條件逐行篩選vt1,將結果插入vt2中
3.JOIN:添加外部行,如果指定了LEFT JOIN,則先遍歷一遍左表的每一行,其中不在vt2的行會被插入到vt2,該行的剩余字段將被填充為NULL,形成vt3;如果指定了RIGHT JOIN也是同理。但如果指定的是INNER JOIN,則不會添加外部行,上述插入過程被忽略,vt2=vt3(所以INNER JOIN的過濾條件放在ON或WHERE里 執(zhí)行結果是沒有區(qū)別的,下文會細說)
4.WHERE:對vt3進行條件過濾,滿足條件的行被輸出到vt4
5.SELECT:取出vt4的指定字段到vt5

從Left join 過程你會發(fā)現(xiàn)步驟要比2要復雜一些,可能會造成一些耗時

2018年1月20日 17:53
編輯回答
膽怯

要看場景的好吧,數(shù)據(jù)量千條, hash join明細比全表掃描快
圖片描述

2017年7月29日 14:04