这是查询(最大的表有大约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
如果我运行它,它会很快执行(大概是.05秒)。它返回13行。
当我在查询末尾添加ORDER BY
子句(按任意列排序)时,查询大约需要10秒。
我现在在生产中使用这个数据库,一切正常。我所有的其他疑问都很快。
有什么想法可能是什么?我在MySQL的查询浏览器中运行查询,并从命令行运行。这两个地方ORDER BY
都很慢。
编辑: Tolgahan ALBAYRAK解决方案有效,但任何人都可以解释它的工作原理吗?
答案 0 :(得分:17)
也许这会有所帮助:
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
答案 1 :(得分:7)
您订购的列是否已编入索引?
索引大大加快了排序和过滤速度。
答案 2 :(得分:2)
您正在选择" UserCourse "我假设是课程和用户之间的连接表(多对多)。 您应该在" UserCourse"中为您需要订购的列编制索引。表
假设你想按照CourseID "" 订购,那么你需要在 UserCourse 表上对其进行索引。
通过连接表中不存在的任何其他列(即UserCourse)进行排序可能需要对连接表进行进一步的非规范化和索引以针对速度进行优化; 换句话说,您需要在连接表中拥有该列的副本并将其编入索引。
<强> P.S。强> Tolgahan Albayrak给出的答案虽然对于这个问题是正确的,但是如果一个人正在做一个&#34; LIMIT x&#34;查询。
答案 3 :(得分:0)
您是否更新了数据库的统计信息?我遇到类似的东西,我有2个相同的查询,唯一的区别是大写字母,一个以1/2秒返回,另一个花了将近5分钟。更新统计信息解决了问题
答案 4 :(得分:0)
它也可能对你有所帮助。基本上它描述了使用复合索引以及如何按顺序工作。
答案 5 :(得分:0)
今天我遇到了同样的问题。一旦我通过连接表中的字段对结果集进行排序,整个查询就非常慢,耗时超过一百秒。
服务器正在运行MySQL 5.0.51a,我偶然发现同样的查询运行速度和它应该总是在MySQL 5.1的服务器上运行一样快。当比较该查询的解释时,我发现显然索引的使用和处理已经发生了很大变化(至少从5.0 - > 5.1)。
因此,如果您遇到这样的问题,也许您的解决方案就是简单地升级您的MySQL