我有四個表,我試圖加入並輸出結果到一個新表。我的代碼如下所示:在mysql中連接表時沒有正確使用索引?
create table tbl
select a.dte, a.permno, (ret - rf) f0_xs_ret, (xs_ret - (betav*xs_mkt)) f0_resid, mkt_cap last_year_mkt_cap, betav beta_value
from a inner join b using (dte)
inner join c on (year(a.dte) = c.yr and a.permno = c.permno)
inner join d on (a.permno = d.permno and year(a.dte)-1 = year(d.dte));
所有的表有多個索引和表a
,(dte, permno)
確定一個唯一的記錄,爲表b
,dte
ID是唯一的記錄,爲表c
,(yr, permno)
ID的唯一記錄併爲表d
,(dte, permno)
確定一個唯一記錄。該解釋從查詢的select
部分是:
+----+-------------+-------+--------+-------------------+---------+---------+---------- ------------------------+--------+-------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+-------------------+---------+---------+---------- ------------------------+--------+-------------------+
| 1 | SIMPLE | d | ALL | idx1 | NULL | NULL | NULL | 264129 | |
| 1 | SIMPLE | c | ref | idx2 | idx2 | 4 | achernya.d.permno | 16 | |
| 1 | SIMPLE | b | ALL | PRIMARY,idx2 | NULL | NULL | NULL | 12336 | Using join buffer |
| 1 | SIMPLE | a | eq_ref | PRIMARY,idx1,idx2 | PRIMARY | 7 | achernya.b.dte,achernya.d.permno | 1 | Using where |
+----+-------------+-------+--------+-------------------+---------+---------+----------------------------------+--------+-------------------+
爲什麼MySQL的要讀這麼多行來處理這件事情?如果我正確閱讀這個,它必須讀(264129*16*12336)
行,這應該需要一個好月份。
可能有人請解釋一下這是怎麼回事呢?
哦 - 我看到的。我的理解是,對於第一個表中讀取的每一行,它必須讀取另一個表中的16 * 12336行。我認爲它會簡單地沿着第一個表的行,然後對第一行的每一行按順序讀取其他行。是不正確的? – Alex 2012-08-15 03:26:37
你是否確定這是理解行列的方法?我瞭解了通過允許mysql轉到表的子集來縮小要掃描的行數量的索引,但是它仍然必須讀取我原始表中每行的整個子集? – Alex 2012-08-15 03:32:55
我讀這個網上:「omputing行進行檢查是比較複雜的,是採取從各行的估計行數頻繁方法聯接和繁殖他們......」他接着說,這是不準確等,但他並沒有說任何關於添加東西的事情。你有什麼資料可以查看嗎?如果這只是一個總和然後我的查詢將已經 – Alex 2012-08-15 03:39:07