简体   繁体   English

具有多个联接的SQL查询会影响性能

[英]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 BYORDER 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 TABLEEXPLAIN SELECT ... ,以便我们对索引进行评论。

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

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