I have a relational MySQL database with almost 4000 records. 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. 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. 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
.
Same as for k.id LIKE kc._keywordID
use = operator instead of LIKE and apply index on field _keywordID
.
Yes, use =
instead of LIKE
; keep LIKE
for when you need wild cards, such as first_name LIKE 'H%'
.
After changing to =
, you may still find the query slow. Consider these:
If you don't need LEFT
, don't use it. 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.
If the GROUP BY
and ORDER BY
are the same, you can avoid a temp table and sort:
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.