简体   繁体   English

MySql查询速度很慢

[英]MySql Query very slow

I run the following query on my database : 我在我的数据库上运行以下查询:

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

And the query runs fine. 查询运行正常。 If I modifiy the query like this : 如果我修改这样的查询:

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

The query becomes very slow ! 查询变得非常慢! The problem is I want to select many columns in table e and f, and the query can take up to 1 minute ! 问题是我想在表e和f中选择许多列,查询最多可能需要1分钟! I tried different modifications but nothing works. 我尝试了不同的修改但没有任何作用 I have indexes on id_* also on e.codega. 我在e.codega上也有关于id_ *的索引。 Enfants has 9000 lines and FichiersEnfants has 20000 lines. Enfants有9000行,FichiersEnfants有20000行。 Any suggestions ? 有什么建议么 ?

Here are the info asked (sorry not having shown them from the beginning) : 以下是要求的信息(抱歉没有从头开始显示):

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

The difference in performance is possibly due to e.id_dernier_fichier being in the index used for the JOIN, but e.codega not being in that index. 性能上的差异可能是由于e.id_dernier_fichier位于用于JOIN的索引中,但e.codega不在索引中。

Without a full definition of both tables, and all of their indexes, it's not possible to tell for certain. 如果没有对这两个表及其所有索引的完整定义,则无法确定。 Also, including the two EXPLAIN PLANs for the two queries would help. 此外,包括两个查询的两个EXPLAIN计划将有所帮助。


For now, however, I can elaborate on a couple of things... 但是现在,我可以详细说明一些事情......

If an INDEX is CLUSTERED (this also applies to PRIMARY KEYs), the data is actually physically stored in the order of the INDEX. 如果INDEX是CLUSTERED(这也适用于PRIMARY KEY),则数据实际上是按INDEX的顺序物理存储的。 This means that knowing you want position x in the INDEX also implicity means you want position x in the TABLE. 这意味着知道你想要在INDEX中的位置x也隐含意味着你想要在表中的位置x

If the INDEX is not clustered, however, the INDEX is just providing a lookup for you. 但是,如果INDEX没有聚集,则INDEX只是为您提供查找。 Effectively saying position x in the INDEX corresponds to position y in the TABLE. 有效地说INDEX中的位置x对应于表中的位置y

The importance here is when accessing fields not specified in the INDEX. 这里的重要性是访问INDEX中未指定的字段。 Doing so means you have to actually go to the TABLE to get the data. 这样做意味着您必须实际转到TABLE以获取数据。 In the case of a CLUSTERED INDEX, you're already there, the overhead of finding that field is pretty low. 在CLUSTERED INDEX的情况下,你已经在那里,找到该字段的开销非常低。 If the INDEX isn't clustered, however, you effectifvely have to JOIN the TABLE to the INDEX, then find the field you're interested in. 但是,如果INDEX不是聚类的,那么您必须将TABLE加入INDEX,然后找到您感兴趣的字段。


Note; 注意; Having a composite index on (id_dernier_fichier, codega) is very different from having one index on just (id_dernier_fichier) and a seperate index on just (codega) . 具有在综合指数(id_dernier_fichier, codega)是从具有仅在一个指数非常不同(id_dernier_fichier)和上只是一个单独的索引(codega)


In the case of your query, I don't think you need to change the code at all. 对于您的查询,我认为您根本不需要更改代码。 But you may benefit from changing the indexes. 但您可能会从更改索引中受益。

You mention that you want to access many fields. 您提到要访问许多字段。 Putting all those fields in a composite index is porbably not the best solution. 将所有这些字段放在复合索引中可能不是最佳解决方案。 Instead you may want to create a CLUSTERED INDEX on (id_dernier_fichier) . 相反,您可能想要创建一个CLUSTERED INDEX (id_dernier_fichier) This will mean that once the *id_dernier_fichier* has been located, you're already in the right place to get all the other fields as well. 这意味着一旦定位了* id_dernier_fichier *,您就已经在正确的位置获得所有其他字段。


EDIT Note About MySQL and CLUSTERED INDEXes 编辑 关于MySQL和CLUSTERED INDEX的注释

13.2.10.1. 13.2.10.1。 Clustered and Secondary Indexes 集群和二级索引

Every InnoDB table has a special index called the clustered index where the data for the rows is stored: 每个InnoDB表都有一个特殊的索引,称为聚簇索引,其中存储了行的数据:

  • If you define a PRIMARY KEY on your table, InnoDB uses it as the clustered index. 如果在表上定义PRIMARY KEY,InnoDB会将其用作聚簇索引。
  • If you do not define a PRIMARY KEY for your table, MySQL picks the first UNIQUE index that has only NOT NULL columns as the primary key and InnoDB uses it as the clustered index. 如果没有为表定义PRIMARY KEY,MySQL会选择第一个只有NOT NULL列作为主键的UNIQUE索引,而InnoDB将它用作聚簇索引。
  • If the table has no PRIMARY KEY or suitable UNIQUE index, InnoDB internally generates a hidden clustered index on a synthetic column containing row ID values. 如果表没有PRIMARY KEY或合适的UNIQUE索引,InnoDB会在包含行ID值的合成列内部生成隐藏的聚簇索引。 The rows are ordered by the ID that InnoDB assigns to the rows in such a table. 行按InnoDB分配给此类表中的行的ID排序。 The row ID is a 6-byte field that increases monotonically as new rows are inserted. 行ID是一个6字节的字段,随着新行的插入而单调增加。 Thus, the rows ordered by the row ID are physically in insertion order. 因此,由行ID排序的行在物理上处于插入顺序。

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

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