当我 ORDER BY 计算列时,查询会显着减慢 - 可以加快速度吗?

Posted

技术标签:

【中文标题】当我 ORDER BY 计算列时,查询会显着减慢 - 可以加快速度吗?【英文标题】:When I ORDER BY a computed column, the query slows significantly - Can this be sped up? 【发布时间】: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 进行分组。 【参考方案1】:

(巩固上面的讨论)

您无法通过计算结果有效地排序。要使此查询快速运行,请创建一个包含c.age-UNIX_TIMESTAMP(c.newdate)ranking 列。然后在id ranking 上创建一个索引,即CREATE INDEX id_ranking ON c (id, ranking) 以使 GROUP BY 和 ORDER BY 都被索引。

【讨论】:

以上是关于当我 ORDER BY 计算列时,查询会显着减慢 - 可以加快速度吗?的主要内容,如果未能解决你的问题,请参考以下文章

ORDER BY 子句是不是会减慢查询速度?

MySQL:ORDER BY 显着降低查询速度

EF Core 3 - 不必要的 ORDER BY 减慢查询

MYSQL在简单查询中使用ORDER BY索引列时使用文件排序

MySQL Order By 减慢连接速度

WebGL 警告:“属性 0 已禁用。这会显着降低性能”