我在我的数据库上运行以下查询:
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_ *的索引。 Enfants有9000行,FichiersEnfants有20000行。有什么建议吗?
以下是要求的信息(抱歉没有从头开始显示):
答案 0 :(得分:2)
性能差异可能是,因为e.id_dernier_fichier
位于用于JOIN的索引中,但e.codega
不在 中 index。
如果没有对两个表及其所有索引的完整定义,则无法确定。此外,包括两个查询的两个EXPLAIN PLAN将有所帮助。
但是现在,我可以详细说明一些事情......
如果INDEX是CLUSTERED(这也适用于PRIMARY KEY),则数据实际上是按INDEX的顺序物理存储的。这意味着您知道在INDEX中想要 位置x 也意味着您需要在TABLE中 位置x 。
但是,如果INDEX不是群集,则INDEX只是为您提供查找。在INDEX中有效地说 位置x 对应于表中的 位置y 。
此处的重要性在于访问未在INDEX中指定的字段。这样做意味着您必须实际转到TABLE以获取数据。在CLUSTERED INDEX的情况下,你已经在那里,找到该字段的开销非常低。但是,如果INDEX不是聚类的,那么您必须将TABLE加入INDEX,然后找到您感兴趣的字段。
请注意;在(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表都有一个特殊的索引,称为聚簇索引,其中存储了行的数据: