2011-06-24 58 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