2010年3月19日 星期五

mysql join的效率問題,子查詢與explain分析

以前學習sql server的時候,不知在那兒得知,先在一個很大的table中篩選資料,得到一個暫存的小檔,再用此檔去進行其他運算,如join,效率會比較好。在mysql中,我使用類似的作法,就是先用子查詢,得出一個暫存的table,再進行處理。


EXPLAIN
SELECT a . * , b . seq , b . weight AS tWeight , b . loss
FROM batch_detail a
LEFT OUTER JOIN scription_main b ON a . prodSeq = b . seq
WHERE a . accSeq = 1
AND a . bNo = 3

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE a ref accSeq,bNo bNo 4 const 1 Using where
1 SIMPLE b eq_ref PRIMARY PRIMARY 4 cook.a.prodSeq 1


第二個表使用子查詢,可以看到mysql對子查詢用where篩選,先產生一個暫存檔derived2(DERIVED是一個子查詢的型態)。再和table b join。
EXPLAIN
SELECT a . * , b . seq , b . weight AS tWeight , b . loss
FROM ( SELECT prodSeq , weight AS totWeight
FROM batch_detail
WHERE accSeq = 1
AND bNo = 3 ) a
LEFT OUTER JOIN scription_main b ON a . prodSeq = b . seq


id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
1 PRIMARY b const PRIMARY PRIMARY 4 const 1
2 DERIVED batch_detail ref accSeq,bNo bNo 4 1 Using where

但使用子查詢,在經過explain分析的效率,感覺並沒有比較好。第一個表中,可以看到mysql自動對where進行優化處理,得出一個row之後,再和另一個表去join。 第二個作法,經explain分析以後,反而多出一個row。



EXPLAIN能夠分析SELECT命令的處理過程。這不僅對於決定是否要為表加上索引很有用,而且對於瞭解MySQL處理複雜連接的過程也很有用。