我有一个关系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`
答案 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 BY
和ORDER BY
相同,则可以避免使用临时表并进行排序:
GROUP BY c.`Last Name`, c.`First Name`, c.id
ORDER BY c.`Last Name`, c.`First Name`, c.id
请提供SHOW CREATE TABLE
和EXPLAIN SELECT ...
,以便我们批评索引。