繁体   English   中英

MySql查询速度很慢

[英]MySql Query very slow

我在我的数据库上运行以下查询:

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行。 有什么建议么 ?

以下是要求的信息(抱歉没有从头开始显示):

表FichiersEnfants表Enfants索引Enfants解释查询1解释查询2

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

如果没有对这两个表及其所有索引的完整定义,则无法确定。 此外,包括两个查询的两个EXPLAIN计划将有所帮助。


但是现在,我可以详细说明一些事情......

如果INDEX是CLUSTERED(这也适用于PRIMARY KEY),则数据实际上是按INDEX的顺序物理存储的。 这意味着知道你想要在INDEX中的位置x也隐含意味着你想要在表中的位置x

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

这里的重要性是访问INDEX中未指定的字段。 这样做意味着您必须实际转到TABLE以获取数据。 在CLUSTERED INDEX的情况下,你已经在那里,找到该字段的开销非常低。 但是,如果INDEX不是聚类的,那么您必须将TABLE加入INDEX,然后找到您感兴趣的字段。


注意; 具有在综合指数(id_dernier_fichier, codega)是从具有仅在一个指数非常不同(id_dernier_fichier)和上只是一个单独的索引(codega)


对于您的查询,我认为您根本不需要更改代码。 但您可能会从更改索引中受益。

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


编辑 关于MySQL和CLUSTERED INDEX的注释

13.2.10.1。 集群和二级索引

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM