2011-06-24 49 views
0

可能重複:
Does MySQL view always do full table scan?優化巨大的MySQL視圖

運行SELECT * FROM vAtom LIMIT 10永遠不會返回(我放棄它48小時後);

explain select * from vAtom limit 10

+----+-------------+---------------+--------+-------------------------------------------+---------------+---------+------------------------------------------------------------------------------------------------+-----------+---------------------------------+ 
| id | select_type | table   | type | possible_keys        | key   | key_len | ref                       | rows  | Extra       | 
+----+-------------+---------------+--------+-------------------------------------------+---------------+---------+------------------------------------------------------------------------------------------------+-----------+---------------------------------+ 
| 1 | SIMPLE  | A    | ALL | primary_index,atom_site_i_3,atom_site_i_4 | NULL   | NULL | NULL                       | 571294166 | Using temporary; Using filesort | 
| 1 | SIMPLE  | S    | ref | primary_index        | primary_index | 12  | PDB.A.Structure_ID                    |   1 | Using index      | 
| 1 | SIMPLE  | C    | eq_ref | PRIMARY,chain_i_1,sid_type,detailed_type | PRIMARY  | 24  | PDB.A.Structure_ID,PDB.A.auth_asym_id               |   1 | Using where      | 
| 1 | SIMPLE  | AT   | eq_ref | primary_index        | primary_index | 24  | PDB.A.Structure_ID,PDB.A.type_symbol               |   1 | Using index      | 
| 1 | SIMPLE  | entityResidue | ref | PRIMARY         | PRIMARY  | 52  | PDB.S.Structure_ID,PDB.A.label_entity_id,PDB.A.label_seq_id,PDB.A.label_comp_id,PDB.C.Chain_ID |   1 | Using where; Using index  | 
| 1 | SIMPLE  | E    | ref | primary_index        | primary_index | 12  | PDB.AT.Structure_ID                   |   1 | Using where      | 
+----+-------------+---------------+--------+-------------------------------------------+---------------+---------+------------------------------------------------------------------------------------------------+-----------+---------------------------------+ 
6 rows in set (0.00 sec) 

你不必告訴我,600M行是很多。我想知道的是爲什麼當我只需要10行時速度很慢,我能從這裏做什麼。

我會很高興發佈show create每請求任何東西(不想讓這個帖子7頁長)

+2

可能是相關的:http://stackoverflow.com/questions/637328/does-mysql-view-always-do-full-table-scan –

+0

這很有用,雖然我的重點是在'極限'問題 – Mikhail

回答

0

我覺得show create將是有益的。看起來您在vAtom上有全表掃描。也許如果你把一個ORDER BY子句放在一個索引字段後面,它會表現得更好。

+0

?你不能在一個視圖索引:( – Mikhail

1

它聲稱使用的是filesort。該視圖必須具有ORDER BY或DISTINCT上的未索引值,或索引不夠具體,以幫助。

要修復它,要麼改變視圖,以便它不需要進行排序,或更改基礎表,讓他們有一個索引,這將使排序快。

+0

當你說「必須有」 - 你說它,因此它的速度慢,或者說,它應該在那裏放 – Mikhail

+0

@Mikhail:更新答案 –

1

表可以有一個內置的排序順序,在你在哪裏沒有指定自己的排序任何查詢此默認踢。所以,你的查詢仍在試圖那些570+萬行進行排序,以便它能夠找到的第一個10

+0

我有一半明白這一點,雖然它很慢,當我沒有指定限制時... – Mikhail

1

我真的不驚訝。考慮一下你只是加入2個表A和B並限制結果集的情況;可能只有表A的最後N行有匹配,那麼數據庫將不得不遍歷'A'中的所有行以獲得N個匹配的行。

如果'B'中有很多行,這將不可避免地會出現這種情況。

你想認爲,這將解決其他方式時,只有在B中的幾行 - 但顯然,這裏並非如此。事實上,IIRC LIMIT對查詢計劃的生成沒有影響 - 即使這樣做,mysql似乎也不能處理查看的推斷謂詞。

如果你提供的基礎表的細節,在每行數和觀點,應該可以編寫一個查詢直接引用的表更高效地運行了很多。或者,根據視圖的使用方式,您可以使用提示獲得所需的行爲。

+0

編寫整個查詢將會起作用(我認爲我已經測試過了),添加一個'where'也可以工作(返回1000個結果爲0.03 S)。請詳細說明「使用提示」 – Mikhail

+0

在A上加入B會更好嗎(在你的情況下)? – Mikhail