首頁 >後端開發 >php教程 >SQL from多重表格和 inner join的區別

SQL from多重表格和 inner join的區別

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB原創
2016-08-04 09:20:172437瀏覽

這是inner join寫法

<code>SELECT
    B.dict_data_name,
    SUM(A.pv) AS pv
FROM
    shw_mo_health_news A
INNER JOIN bas_dict_data B ON A.third_name_dictid = B.item_id
WHERE
    A.class_level = 3
AND B.class_id = 1012
AND A.collect_date >= '2016-04-01'
AND A.collect_date <= '2016-05-31'
GROUP BY
    A.third_name_dictid
ORDER BY
    pv DESC;</code>

實際查詢時間用戶約0.6S

用explain 查看:
SQL from多重表格和 inner join的區別


這是from 多表寫法

<code>SELECT
    B.dict_data_name,
    A.PV
FROM
    (
        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
    ) B
WHERE
    A.third_name_dictid = B.item_id
ORDER BY
    PV DESC</code>

實際用時0.03s左右

Explain查看
SQL from多重表格和 inner join的區別


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

回覆內容:

這是inner join寫法

<code>SELECT
    B.dict_data_name,
    SUM(A.pv) AS pv
FROM
    shw_mo_health_news A
INNER JOIN bas_dict_data B ON A.third_name_dictid = B.item_id
WHERE
    A.class_level = 3
AND B.class_id = 1012
AND A.collect_date >= '2016-04-01'
AND A.collect_date <= '2016-05-31'
GROUP BY
    A.third_name_dictid
ORDER BY
    pv DESC;</code>

實際查詢時間用戶約0.6S

用explain 查看:
SQL from多重表格和 inner join的區別


這是from 多表寫法

<code>SELECT
    B.dict_data_name,
    A.PV
FROM
    (
        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
    ) B
WHERE
    A.third_name_dictid = B.item_id
ORDER BY
    PV DESC</code>

實際用時0.03s左右

Explain查看
SQL from多重表格和 inner join的區別


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

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

<code>SELECT
    B.dict_data_name,
    SUM(A.pv) AS pv
FROM
    shw_mo_health_news A
INNER 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_id

GROUP BY
    A.third_name_dictid
ORDER BY
    pv DESC;</code>

我覺得性能會明顯不同。

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


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

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

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

<code>-- 查询1
SELECT * FROM table_a
WHERE A IN (
    SELECT A FROM table_b
    WHERE B = 'x'
)
-- 查询2
SELECT table_a.* FROM table_a A
    INNER JOIN table_b B ON a.A = b.A
WHERE B.B = 'x'</code>

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

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn