[英]SQL query with multiple joins impacting performance
I have a relational MySQL database with almost 4000 records. 我有一个具有近4000条记录的关系MySQL数据库。 The contacts table is related to both the keywords and notes tables with manny-to-many relationships. 联系人表与具有一对多关系的关键字和注释表相关。 I wrote a query (with PHP) that would retrieve each contact record and, for each contact, all related notes and keywords in a group concat function. 我编写了一个查询(使用PHP),该查询将检索每个联系人记录,并为每个联系人获取组concat函数中的所有相关注释和关键字。 If I only grab the contacts, the query performs relatively quickly but with the two left joins and group concat, it takes almost 30 seconds. 如果仅抓住联系人,查询将相对快速地执行,但是通过两个左联接和组连接,查询将花费近30秒钟。 Is there a way to speed this up? 有没有办法加快速度?
Here is my query: 这是我的查询:
SELECT c.*, GROUP_CONCAT(DISTINCT n.id, '[-]', n.value, '' SEPARATOR '---') as notes,
GROUP_CONCAT(DISTINCT kk.id, '[-]', kk.value) as keywords
FROM contacts c
LEFT JOIN notes n ON c.id LIKE n._contactID
LEFT JOIN
( SELECT k.*, kc._contactID as contactID
FROM keywords k
INNER JOIN keywords_contacts kc ON k.id LIKE kc._keywordID
) kk ON kk.contactID LIKE c.id
GROUP BY c.id
ORDER BY c.`Last Name`, c.`First Name`
I your query I can see c.id LIKE n._contactID
, here LIKE is making performace low so use = operator and give index to foreign key field _contactID
. 在您的查询中,我可以看到c.id LIKE n._contactID
,这里LIKE的性能降低,因此请使用=运算符并为外键字段_contactID
提供索引。
Same as for k.id LIKE kc._keywordID
use = operator instead of LIKE and apply index on field _keywordID
. 与k.id LIKE kc._keywordID
相同k.id LIKE kc._keywordID
使用=运算符代替LIKE并在字段_keywordID
上应用索引。
Yes, use =
instead of LIKE
; 是的,使用=
代替LIKE
; keep LIKE
for when you need wild cards, such as first_name LIKE 'H%'
. 在需要通配符(例如first_name LIKE 'H%'
时保留LIKE
。
After changing to =
, you may still find the query slow. 更改为=
,您仍然可能发现查询变慢。 Consider these: 考虑这些:
If you don't need LEFT
, don't use it. 如果不需要LEFT
,请不要使用它。 Normally it is faster to start with the 'table' that is a subquery (see LEFT JOIN ( SELECT ...)
), but the use of LEFT
tends to inhibit such. 通常,从作为子查询的“表”开始更快(请参阅LEFT JOIN ( SELECT ...)
),但是使用LEFT
往往会抑制这种情况。
If the GROUP BY
and ORDER BY
are the same, you can avoid a temp table and sort: 如果GROUP BY
和ORDER BY
相同,则可以避免使用临时表并进行排序:
GROUP BY c.`Last Name`, c.`First Name`, c.id
ORDER BY c.`Last Name`, c.`First Name`, c.id
Please provide SHOW CREATE TABLE
and EXPLAIN SELECT ...
, so we can critique the indexes. 请提供SHOW CREATE TABLE
和EXPLAIN SELECT ...
,以便我们对索引进行评论。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.