使用 ORDER BY 时查询速度慢

问题描述 投票:0回答:8

这是查询(最大的表有大约 40,000 行)

SELECT
  Course.CourseID,
  Course.Description,
  UserCourse.UserID,
  UserCourse.TimeAllowed,
  UserCourse.CreatedOn,
  UserCourse.PassedOn,
  UserCourse.IssuedOn,
  C.LessonCnt
FROM
  UserCourse
INNER JOIN
  Course
USING(CourseID)
INNER JOIN
(
  SELECT CourseID, COUNT(*) AS LessonCnt FROM CourseSection GROUP BY CourseID
) C
USING(CourseID)
WHERE 
  UserCourse.UserID = 8810

如果我运行它,它执行得非常快(大约 0.05 秒)。它返回 13 行。

当我在查询末尾添加

ORDER BY
子句(按任何列排序)时,查询大约需要 10 秒。

我现在在生产中使用这个数据库,一切正常。我所有其他查询都很快。

有什么想法吗?我在 MySQL 的查询浏览器中以及从命令行运行了查询。这两个地方都非常慢,

ORDER BY

编辑: Tolgahan ALBAYRAK 解决方案有效,但任何人都可以解释为什么它有效吗?

mysql sql-order-by
8个回答
18
投票

也许这有帮助:

SELECT * FROM (    
     SELECT
      Course.CourseID,
      Course.Description,
      UserCourse.UserID,
      UserCourse.TimeAllowed,
      UserCourse.CreatedOn,
      UserCourse.PassedOn,
      UserCourse.IssuedOn,
      C.LessonCnt
    FROM
      UserCourse
    INNER JOIN
      Course
    USING(CourseID)
    INNER JOIN
    (
      SELECT CourseID, COUNT(*) AS LessonCnt FROM CourseSection GROUP BY CourseID
    ) C
    USING(CourseID)
    WHERE 
      UserCourse.UserID = 8810
) ORDER BY CourseID

9
投票

您要排序的列是否已编入索引?

索引极大地加快了排序和过滤速度。


3
投票

您正在从“UserCourse”中进行选择,我认为它是课程和用户之间的连接表(多对多)。 您应该在“UserCourse”表中对需要排序的列进行索引。

假设你想“order by CourseID”,那么你需要在UserCourse表上建立索引。

按连接表中不存在的任何其他列(即 UserCourse)进行排序可能需要在连接表上进行进一步的非规范化和索引,以优化速度; 换句话说,您需要在连接表中拥有该列的副本并为其建立索引。

附注 Tolgahan Albayrak 给出的答案虽然对于这个问题是正确的,但在执行“LIMIT x”查询的情况下不会产生所需的结果。


2
投票
您更新了数据库的统计数据吗?我遇到了类似的情况,我有 2 个相同的查询,唯一的区别是大写字母,一个在 1/2 秒内返回,另一个花了近 5 分钟。更新统计数据解决了问题


2
投票
意识到答案为时已晚,但是我刚刚遇到了类似的问题,通过将查询时间从几秒增加到 5 分钟来添加顺序,并尝试了大多数其他加快速度的建议,注意到 /tmp 文件变得 12G对于这个查询。更改了查询,使得返回的 varchar(20000) 字段为“trim(”ed,并且性能显着提高(回到秒)。因此,我想值得检查您是否在查询中返回大 varchar,如果是,处理它们(也许是 substring(x, 1, length(x)) ??如果你不想修剪它们。 查询返回 500k 行,/tmp 文件指示每行使用大约 20k 数据。


1
投票
今天我遇到了同样的问题。当我按连接表中的字段对结果集进行排序时,整个查询速度非常慢,花费了一百多秒。

服务器正在运行 MySQL 5.0.51a,偶然我注意到相同的查询运行速度与在 MySQL 5.1 服务器上应有的速度一样快。在比较该查询的解释时,我发现显然索引的使用和处理发生了很大变化(至少从 5.0 -> 5.1)。

所以如果你遇到这样的问题,也许你的解决办法就是简单地升级你的MySQL


0
投票
之前曾在这里问过类似的问题。

它也可能对你有帮助。基本上它描述了使用复合索引以及 order by 的工作原理。


0
投票

select * from ( SELECT * FROM Table1 T1 INNER JOIN Table2 T2 ON T1.CourseID = T2.CourseID ) AS Table3 ORDER BY CourseID

© www.soinside.com 2019 - 2024. All rights reserved.