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