使用過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 子查詢 排序 MySQL的子查詢中排序
起因 create table reading record id int primary key auto increment,自增主鍵 file varchar 255 閱讀檔名 user varchar 255 讀者 expend int,閱讀時長 time datetime,閱讀時間 一開始...
MySQL 中的子查詢
單值子查詢的的返回值必須只有一行記錄,而且只能有乙個列。這樣的子查詢又被稱為標量子查詢。例 select 1 as f1,2,select min fyearpublished from t book select max fyearpublished from t book as f4 列值子查詢...
資料庫 子查詢《mysql子查詢的弱點》
mysql的子查詢的優化不是很友好,一直有受業界批評比較多.關於mysql的查詢有兩個知識點 1.第乙個為mysql在處理所有的查詢的時候都強行轉換為聯接來執行,將每個查詢包括多表中關聯匹配,關聯 子查詢,union,甚至單錶的的查詢都處理為聯接,接著mysql執行聯接,把每個聯接在處理為乙個巢狀迴...