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

时间:2016-08-24 06:57:05

标签: php mysql sql performance join

我有一个关系MySQL数据库,有近4000条记录。联系人表与关键字和注释表都有关联,这些关键字和注释表具有manny-to-many关系。我编写了一个查询(使用PHP),它将检索每个联系人记录,并为每个联系人检索组concat函数中的所有相关注释和关键字。如果我只抓取联系人,查询执行速度相对较快,但是使用两个左连接和组连接,则需要将近30秒。有没有办法加快速度呢?

这是我的问题:

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`

2 个答案:

答案 0 :(得分:1)

我的查询我可以看到c.id LIKE n._contactID,这里LIKE正在使性能低,所以使用=运算符并为外键字段_contactID提供索引。

k.id LIKE kc._keywordID use =运算符相同而不是LIKE,并在字段_keywordID上应用索引。

答案 1 :(得分:0)

是的,使用=代替LIKE;在需要通配符时保留LIKE,例如first_name LIKE 'H%'

更改为=后,您仍可能发现查询速度很慢。考虑这些:

如果您不需要LEFT,请不要使用它。通常,从作为子查询的'table'开始会更快(参见LEFT JOIN ( SELECT ...)),但LEFT的使用往往会抑制这种情况。

如果GROUP BYORDER BY相同,则可以避免使用临时表并进行排序:

GROUP BY c.`Last Name`, c.`First Name`, c.id
ORDER BY c.`Last Name`, c.`First Name`, c.id

请提供SHOW CREATE TABLEEXPLAIN SELECT ...,以便我们批评索引。