简体   繁体   English

MySQL左连接查询太慢

[英]MySQL left join query too slow

I'm using this SQL query to join two tables and it takes 10 seconds even with a limit of 10. I've checked if the tables are indexed and they are so I'm out of ideas. 我正在使用此SQL查询连接两个表,即使限制为10,也要花10秒。我检查了表是否已建立索引并且它们是否索引,所以我没有主意。 Any help will be appreciated. 任何帮助将不胜感激。

SELECT * FROM client_registration_request
LEFT JOIN customers ON (client_registration_request.customer_reference=customers.reference) 
LEFT JOIN region_info ON ( customers.country = region_info.id ) 
WHERE client_registration_request.client = 23
LIMIT 10

Here are the results from explain select 这是来自说明选择的结果

说明选择

client_registration_request index client_registration_request索引

client_registration_request索引

customers index 客户指数

客户指数

and region_info index 和region_info索引 和region_info索引

always make sure the fields you are using for your JOIN - conditions are indexed: 始终确保用于JOIN的字段已被索引-条件:

ALTER TABLE `client_registration_request` ADD INDEX `customer_reference` (`customer_reference`);
ALTER TABLE `customers` ADD INDEX `reference` (`reference`);

.. and so on. .. 等等。

update: your EXPLAIN shows that your indexed keys customers table are not used. 更新:您的EXPLAIN显示未使用索引关键字customers表。 so try to re-index them: 因此,请尝试重新索引它们:

ALTER TABLE `customers` ADD INDEX `reference` (`reference`);
ALTER TABLE `customers` ADD INDEX `country` (`country`);

The way you have written the query is limiting and filtering the results after the two left join have performed, that's why it's taking the same time to query. 您编写查询的方式是在执行两个左联接之后限制并过滤结果,这就是为什么它需要花费相同的时间来查询的原因。

To make it quicker you need to limit and filter it as soon as possible, in your case you want to limit and filter it before any join. 为了使其更快,您需要尽快对其进行限制和过滤,如果您想在进行任何连接之前对其进行限制和过滤。

As you are using LEFT JOINS, you can limit and filter the first table and still get the same result. 在使用LEFT JOINS时,您可以限制和过滤第一个表,但仍得到相同的结果。 Try this: 尝试这个:

SELECT * FROM 
(SELECT * FROM client_registration_request WHERE client_registration_request.client = 23 LIMIT 10) client_registration_request_TMP
LEFT JOIN customers ON (client_registration_request_TMP.customer_reference=customers.reference) 
LEFT JOIN region_info ON ( customers.country = region_info.id )

Here is your query, using table aliases (so I find it easier to follow): 这是使用表别名的查询(因此,我觉得更容易理解):

SELECT *
FROM client_registration_request crr LEFT JOIN
     customers c
     ON crr.customer_reference = c.reference LEFT JOIN
     region_info r
     ON c.country = r.id
WHERE crr.client = 23
LIMIT 10

The most important index is on on client_registration_request(client) . 最重要的索引在client_registration_request(client) But, I would include the other join columns in this. 但是,我将在其中包括其他join列。 So, the first index is client_registration_request(client, reference, country) . 因此,第一个索引是client_registration_request(client, reference, country) You can create this as: 您可以将其创建为:

create index idx_client_registration_request_3 on client_registration_request(client, reference, country);

I assume that the keys in the other tables are already primary keys or indexed. 我假设其他表中的键已经是主键或已索引。 If not, you should build indexes on them too customer(reference) and region_info(country) . 如果没有,您也应该在它们上建立索引customer(reference)region_info(country)

Using a LIMIT without an ORDER BY is suspicious. 在没有ORDER BY情况下使用LIMIT是可疑的。 You will be getting an arbitrary set of matching rows when you run the query -- you cannot guarantee that two runs would return the same set. 运行查询时,您将获得任意一组匹配的行-您不能保证两次运行都会返回相同的行。

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

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