2011-08-09 168 views
3

我在我的数据库中运行以下查询:MySQL查询很慢

SELECT e.id_dernier_fichier 
FROM Enfants e JOIN FichiersEnfants f 
ON e.id_dernier_fichier = f.id_fichier_enfant 

和查询运行正常。如果我修改这样的查询:

SELECT e.codega 
FROM Enfants e JOIN FichiersEnfants f 
ON e.id_dernier_fichier = f.id_fichier_enfant 

查询变得非常慢!问题是我想在表e和f中选择许多列,查询最多需要1分钟!我尝试了不同的修改,但没有任何效果我在e.codega上也有id_ *上的索引。婴儿有9000条生产线,FichiersEnfants有20000条生产线。有什么建议么 ?

这里是要求信息(抱歉,没有从一开始就显示它们):

Table FichiersEnfants Table Enfants Index Enfants Explain Query 1 Explain Query 2

+0

这些表中的任何一个实际上是一个视图,你可以在这里张贴查询与EXPLAIN结果。 –

+0

表格架构?索引定义?表中的记录数量? MySQL版本(有点帮助)?硬件规格? – ajreal

+0

e.codega和e.id_dernier_fichier的数据类型是什么? – jadarnel27

回答

2

在性能上的差异是可能由于e.id_dernier_fichier在被用于JOIN的索引,但e.codega不在索引。

如果没有这两个表及其所有索引的完整定义,则无法确定。另外,为两个查询包含两个EXPLAIN PLAN将会有所帮助。


但就目前而言,我如果聚簇索引详细说明几件事情......

(这也适用于主键),数据实际物理存储在INDEX的顺序。这意味着,知道你要在INDEX 位置x也含蓄表示要在表位置x

但是,如果INDEX未被聚集,INDEX只是为您提供查找。有效地说位置x在INDEX对应于位置y在表中。

这里的重要性是访问未在INDEX中指定的字段。这样做意味着您必须切实转到TABLE以获取数据。在一个CLUSTERED INDEX的情况下,你已经在那里了,找到这个字段的开销很小。如果指数不聚集,但是,你effectifvely必须将表连接到索引,然后找到你感兴趣的领域


注意。在(id_dernier_fichier, codega)上有一个复合指数,它与仅在(id_dernier_fichier)上的一个指数和在(codega)上的单独指数有很大不同。


在您的查询的情况下,我不认为你需要做任何改动的代码。但你可能受益于改变指标。

你提到你想访问很多字段。将所有这些字段放在一个复合索引中可能不是最好的解决方案。相反,您可能需要在(id_dernier_fichier)上创建一个CLUSTERED INDEX。这意味着一旦找到了* id_dernier_fichier *,您就已经在正确的位置获得所有其他字段。


编辑Note About MySQL and CLUSTERED INDEXes

13.2.10.1。群集和辅助索引

每个InnoDB表有一个特殊的索引称为其中的行中的数据被存储在聚簇索引:

  • 如果你定义你的表的主键,InnoDB使用它作为聚集指数。
  • 如果您没有为您的表定义PRIMARY KEY,MySQL会选择第一个只有NOT NULL列作为主键的UNIQUE索引,而InnoDB将它用作聚簇索引。
  • 如果表没有PRIMARY KEY或合适的UNIQUE索引,InnoDB会在包含行ID值的合成列内部生成隐藏聚簇索引。这些行按照InnoDB分配给此表中的行的ID进行排序。行ID是一个6字节的字段,随着新行的插入而单调递增。因此,由行ID排序的行在物理上处于插入顺序。
+0

OP提到这两个字段都被编入索引。 – jadarnel27

+0

对不起,我现在在我的问题中添加了所有信息。感谢您的帮助! – Emanuel

+0

@ jadarnel27:这是真的,但没有提及它们是否是单独的索引,复合索引,并且缺少EXPLAIN PLAN没有提及哪些索引正在用于这些查询。所有这些信息对于理解查询的性能特征都是至关重要的。 – MatBailie