【发布时间】:2012-06-19 23:41:59
【问题描述】:
以下查询需要 25 秒以上才能完成:
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
索引:
- c.id PRIMARY
- c.age 索引
- c.newdate 索引
- uc.id_user, uc.id_cluster PRIMARY
- d.id PRIMARY
- d.id_cluster 索引
- dt0.id_document, dt0.id_term PRIMARY
- dt0.id_document 索引
- dt0.id_term 索引
- t0.id 主要
- t0.normalizacion FULLTEXT
如果我删除 ORDER BY 子句,只需要 2 秒。
我一直在搜索,发现 GROUP BY 和 ORDER BY 必须使用相同的索引(尝试按 c.id 排序并花费 2 或 3 秒)。如何将查询更改为更快?
【问题讨论】:
-
2 秒可以接受吗?
-
@cheeken 是的。特别考虑到当前的 25 秒。
-
这里的基本问题是不能通过排名来索引,因为它是实时计算的。我不确定你的表结构和列的含义,但不知何故你应该尝试有一个固定的列来排序。
-
@cen 我尝试创建一个列 c.age2 = c.age-UNIX_TIMESTAMP(c.newdate) 并按它排序(因为 UNIX_TIMESTAMP() 是一个常量,可以出于排序目的而删除)。但是,这并没有缩短查询的时间。
-
@cen 是的。但我认为 MySQL 不能使用该索引,因为它使用 c.id 进行分组。
标签: mysql sql-order-by query-optimization