问题
The following query is taking more than 25 seconds to complete:
SELECT c.* , (c.age+ (UNIX_TIMESTAMP()-UNIX_TIMESTAMP(c.newdate))) AS ranking , IF(uc.id_user = 7,1,0) AS favorite
FROM c
LEFT OUTER JOIN uc ON uc.id_cluster = c.id AND uc.id_user = '7'
LEFT OUTER JOIN d ON d.id_cluster = c.id
LEFT OUTER JOIN dt0 ON dt0.id_document = d.id
LEFT OUTER JOIN t0 ON dt0.id_term = t0.id
WHERE MATCH(t0.normalizacion) AGAINST ('term' IN NATURAL LANGUAGE MODE)
GROUP BY c.id
ORDER BY ranking ASC
LIMIT 30
Indexes:
- c.id PRIMARY
- c.age INDEX
- c.newdate INDEX
- uc.id_user, uc.id_cluster PRIMARY
- d.id PRIMARY
- d.id_cluster INDEX
- dt0.id_document, dt0.id_term PRIMARY
- dt0.id_document INDEX
- dt0.id_term INDEX
- t0.id PRIMARY
- t0.normalizacion FULLTEXT
If I remove the ORDER BY clause, it takes only 2 seconds.
I've been searching and found that the same index has to be used for both GROUP BY and ORDER BY (tried ordering by c.id and took 2 or 3 seconds). How can I change the query to be faster?
回答1:
(consolidating the discussion above)
You can't order efficiently by a computation result. To make this query work fast, create a ranking
column that contains c.age-UNIX_TIMESTAMP(c.newdate)
. Then create an index on id
and ranking
, i.e. CREATE INDEX id_ranking ON c (id, ranking)
to make both GROUP BY and ORDER BY indexed.
来源:https://stackoverflow.com/questions/11111020/when-i-order-by-a-computed-column-the-query-slows-significantly-can-this-be-s