优化恶意MySQL视图

时间:2011-06-24 15:06:46

标签: mysql

  

可能重复:
  Does MySQL view always do full table scan?

正在运行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页)

4 个答案:

答案 0 :(得分:1)

它声称正在使用filesort。视图必须对未编制索引的值具有ORDER BY或DISTINCT,否则索引的具体程度不足以提供帮助。

要修复它,要么更改视图以使其不需要排序,要么更改基础表,以便它们具有可以快速排序的索引。

答案 1 :(得分:1)

表可以有内置的排序顺序,默认情况下会在您未指定自己的排序的任何查询中启动。因此,您的查询仍在尝试对这些超过570万行进行排序,以便找到前10行。

答案 2 :(得分:1)

我并不感到惊讶。考虑一下您只是连接2个表A和B并限制结果集的情况;可能只有表A中的最后N行具有匹配,那么数据库必须遍历'A'中的所有行才能获得N个匹配的行。

如果'B'中有很多行,这将不可避免地出现这种情况。

你觉得当B中只有几行时它会反过来 - 但显然情况并非如此。实际上,IIRC LIMIT对查询计划的生成没有任何影响 - 即使它确实如此,mysql似乎也无法应对视图的推送谓词。

如果您提供了基础表的详细信息,每个视图中的行数和视图,则应该可以编写直接引用表的查询,这些查询运行效率更高。或者,根据视图的使用方式,您可以使用提示获得所需的行为。

答案 3 :(得分:0)

我认为show create会很有用。看起来您在vAtom上有全表扫描。也许如果你在索引字段之后放置一个ORDER BY子句,它会表现得更好。