SQL from多表和 inner join的區別

來源:互聯網
上載者:User

這是inner join寫法

SELECT    B.dict_data_name,    SUM(A.pv) AS pvFROM    shw_mo_health_news AINNER JOIN bas_dict_data B ON A.third_name_dictid = B.item_idWHERE    A.class_level = 3AND B.class_id = 1012AND A.collect_date >= '2016-04-01'AND A.collect_date <= '2016-05-31'GROUP BY    A.third_name_dictidORDER BY    pv DESC;

實際查詢時間使用者0.6S左右

用explain 查看:

這是from 多表寫法

SELECT    B.dict_data_name,    A.PVFROM    (        SELECT            hn.third_name_dictid,            SUM(hn.pv) AS PV        FROM            shw_mo_health_news hn        WHERE            hn.class_level = 3        AND hn.collect_date >= '2016-04-01'        AND hn.collect_date <= '2016-05-31'        GROUP BY            hn.third_name_dictid    ) A,    (        SELECT            dd.item_id,            dd.dict_data_name        FROM            bas_dict_data dd        WHERE            dd.class_id = 1012    ) BWHERE    A.third_name_dictid = B.item_idORDER BY    PV DESC

實際用時0.03s左右

Explain查看

為什麼這兩種查詢方式的效率會有這麼大的差別呢?
網上很多都說這兩種寫法的效率是差不多的;但是我這一個是0.6 和一個0.03,兩者差別還是挺大的,這是什麼原因造成的呢?是因為我寫的SQl語句有問題還是別的原因?

回複內容:

這是inner join寫法

SELECT    B.dict_data_name,    SUM(A.pv) AS pvFROM    shw_mo_health_news AINNER JOIN bas_dict_data B ON A.third_name_dictid = B.item_idWHERE    A.class_level = 3AND B.class_id = 1012AND A.collect_date >= '2016-04-01'AND A.collect_date <= '2016-05-31'GROUP BY    A.third_name_dictidORDER BY    pv DESC;

實際查詢時間使用者0.6S左右

用explain 查看:

這是from 多表寫法

SELECT    B.dict_data_name,    A.PVFROM    (        SELECT            hn.third_name_dictid,            SUM(hn.pv) AS PV        FROM            shw_mo_health_news hn        WHERE            hn.class_level = 3        AND hn.collect_date >= '2016-04-01'        AND hn.collect_date <= '2016-05-31'        GROUP BY            hn.third_name_dictid    ) A,    (        SELECT            dd.item_id,            dd.dict_data_name        FROM            bas_dict_data dd        WHERE            dd.class_id = 1012    ) BWHERE    A.third_name_dictid = B.item_idORDER BY    PV DESC

實際用時0.03s左右

Explain查看

為什麼這兩種查詢方式的效率會有這麼大的差別呢?
網上很多都說這兩種寫法的效率是差不多的;但是我這一個是0.6 和一個0.03,兩者差別還是挺大的,這是什麼原因造成的呢?是因為我寫的SQl語句有問題還是別的原因?

應該是串連損耗吧,我覺得是因為你使用的條件都沒有索引造成的。如果欄位進行了適當的索引,由於mysql會自動對sql語句最佳化的原因,最終查詢語句是一樣的,效能相同,而沒有索引的的時候所謂的最佳化也就不存在了,這個時候最終查詢語句基本等同於你提交的sql。
你可以試試

SELECT    B.dict_data_name,    SUM(A.pv) AS pvFROM    shw_mo_health_news AINNER JOIN bas_dict_data B ON A.class_level = 3 and A.collect_date >= '2016-04-01'AND A.collect_date <= '2016-05-31' and B.class_id=1012 and  A.third_name_dictid = B.item_idGROUP BY    A.third_name_dictidORDER BY    pv DESC;

我覺得效能會明顯不同。

一樣的,屬於 SQL-89 與 SQL-92 不同規範。參見 https://en.wikipedia.org/wiki...

查到一個相關問答,其中有個回答恰好是您這個問題的 https://community.microstrate...

這裡第2個SQL由於有子查詢會有額外的開銷(暫存資料表)。
第2個SQL為什麼會比第1個SQL,根據執行計畫並沒有看出什麼,感覺只是個例外並不能說明什麼

理論上說,子查詢和JOIN沒有本質區別,在查詢分析器合理的最佳化之後應該是等效的。但是也正是由於查詢分析器的各種缺陷,有些時候有些版本的資料庫對子查詢支援得更好,有些則對JOIN支援得更好。MySQL來說我見過的大部分版本子查詢和JOIN是等效的,但是要小心的是子查詢位於WHERE中的情境,比如:

-- 查詢1SELECT * FROM table_aWHERE A IN (    SELECT A FROM table_b    WHERE B = 'x')-- 查詢2SELECT table_a.* FROM table_a A    INNER JOIN table_b B ON a.A = b.AWHERE B.B = 'x'

這就是一個典型的MySQL查詢分析器失效的情境。table_aA欄位有索引的情況下理論上查詢1和查詢2應該等效,但實際上MySQL 5.x的版本中查詢2的效能要明顯優於查詢1。這在Stackoverflow上有人討論,是一個存在近10年的已知問題。必須要升級到6.0.x才會得到修複。所以,對於哪個更優的問題,最可靠的辦法只有自己去看explain的結果再下結論。
對於你的兩個查詢,其實執行計畫都是不一樣的,很明顯第二個的消耗要更大,時間差不多隻是因為多出來的兩步得到的資料量並不太大。再者這兩個查詢其實也不是等價的,都無從比較。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.