mysql left join 與子查詢的性能比較 例子


使用數據庫為mysql的官方示例數據庫employees,可以從這下載:https://github.com/datacharmer/test_db

介紹:

   使用到了employees的兩個表,分別是員工表(employees, 30w24數據),部門經理表(dept_manager 24數據),兩張表都有emp_no,員工編號字段,並且設置了主鍵索引。 

   要求查詢所有非經理的員工數據:

 

左連接

select e.* from employees e LEFT JOIN dept_manager d on e.emp_no = d.emp_no where d.emp_no is null

執行結果:0.651s 

執行計划:

  

 

 

 

子查詢

select * from employees e where e.emp_no not in (select emp_no from dept_manager )

執行結果:0.260s

執行計划:

  

 

 

===============================================

不像一般討論的那樣,這個場景子查詢性能更好,但是具體原因只是看執行計划體現不出,只感覺Extra列可能是重要原因。

實際分析涉及到了Mysql內部實現原理了,咱目前的水平不足,無法解釋。

先放一波猜測記錄,若未來能力夠了再回來驗證。

  「

    子查詢的子部分非常快,查詢的結果作為外層where條件,使得外層可以走索引,實際並沒有遍歷30W數據,即:

      1. 查詢子表所有數據(24條)(非常快,單獨執行0.032s,在子查詢中應該會增加耗時)

      2. 返回子表的主鍵(24條)(非常快)

      3. 用子表返回的主鍵 索引查找外層數據( < 0.23s )

    而

    左連接SQL 由於必須連接后才能過濾右側為空的數據,導致遍歷了1遍的左表,左表每行數據索引1次右表,相當於至少遍歷了2次左表

      1. 遍歷左表所有數據 ( < 0.2s )

      2. 所有左表數據關聯右表( 這部耗時最多,總 < 0.6s,兩倍於步驟1)

      3. 遍歷左表過濾非空 ( 非常快)

   」

 

 

在貼吧看到某個貼后有感而發,測了下。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM