首頁 >資料庫 >mysql教程 >關於在生產庫中遇到mysql的子查詢範例詳解

關於在生產庫中遇到mysql的子查詢範例詳解

黄舟
黄舟原創
2017-08-13 10:56:461202瀏覽

使用過oracle或其他關係型資料庫的DBA或是開發人員都有這樣的經驗,在子查詢上都認為資料庫已經做過最佳化,能夠很好的選擇驅動表執行,然後在把該經驗移植到mysql資料庫上,但不幸的是,mysql在子查詢的處理上有可能會讓你大失所望,在我們的生產系統上就由於碰到了這個問題:

select  i_id, sum(i_sell) as i_sell
from table_data
where i_id in (select i_id from table_data where Gmt_create >= ‘2011-10-07 00:00:00’)
group by i_id;

(備註:sql的業務邏輯可以打個比方:先查詢10-07號新賣出的100本書,然後在查詢這新賣出的100本書在全年的銷售情況)。

這條sql之所以出現的效能問題在於mysql優化器在處理子查詢的弱點,mysql優化器在處理子查詢的時候,會將子查詢改寫。通常情況下,我們希望由內到外,先完成子查詢的結果,然後在用子查詢來驅動外查詢的表,完成查詢;但是mysql處理為將會先掃描外面表中的所有數據,每條資料將會傳到子查詢中與子查詢關聯,如果外表很大的話,那麼效能上將會出現問題;

針對上面的查詢,由於table_data這張表的資料有70W的數據,同時子查詢中的資料較多,有大量是重複的,這樣就需要關聯近70W次,大量的關聯導致這條sql執行了幾個小時也沒有執行完成,所以我們需要改寫sql:

SELECT t2.i_id, SUM(t2.i_sell) AS sold
FROM (SELECT distinct i_id FROM table_data
WHERE gmt_create >= ‘2011-10-07 00:00:00’) t1,  table_data t2
WHERE t1.i_id = t2.i_id GROUP BY t2.i_id;

我們將子查詢改為關聯,同時在子查詢中加上distinct,減少t1關聯t2的次數;

改造後,sql的執行時間降到100ms以內。 

以上是關於在生產庫中遇到mysql的子查詢範例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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