【问题标题】:How do I improve SELECT subquery in MySQL?如何改进 MySQL 中的 SELECT 子查询?
【发布时间】:2015-09-22 20:25:01
【问题描述】:

我有一个学生表和第二个能书。我正在尝试获取学生列表以及他们拥有的书籍数量。

"SELECT 
    StudentID, 
    FullName,
    book_count.ct
FROM 
    students
LEFT JOIN (
    SELECT
        StudentID,
        COUNT(DISTINCT id) AS ct
    FROM
        books
    GROUP BY
        StudentID
    ) AS book_count
ON 
    book_count.StudentID = students.StudentID
ORDER BY
    students.FullName ASC
LIMIT 0, 30;

这个查询大约需要 6 秒的时间来运行,并且随着书籍的增加,它会变得越来越慢。查看查询配置文件 > 90% 的时间是花在“复制到临时表”上。问题是我的子选择查询获取书籍搜索的计数并总计整个书籍表,无论我可能查找多少学生,在我的情况下为 30。我该如何提高这方面的性能?谢谢。

【问题讨论】:

  • 子查询中是否需要 DISTINCT?这可能对性能没有任何帮助。如果书籍中的记录基于 studentID 和 id 是唯一的,那么我认为您不需要它。我也不完全确定您是否需要子查询,但我必须对其进行测试。似乎您可以直接将书籍加入学生,按学生 ID 和姓名分组,然后计算书籍 ID。

标签: mysql subquery query-performance


【解决方案1】:

改成

"SELECT 
    StudentID, 
    FullName,
    ( SELECT
        COUNT(id)
    FROM
        books
    where books.StudentID = students.StudentID
    ) AS book_count
FROM 
    students
ORDER BY
    students.FullName ASC
LIMIT 0, 30;"

在学生列中添加全名索引 和书籍表中的 StudentID。

【讨论】:

    【解决方案2】:

    试试这个:

    SELECT StudentID, FullName,COUNT(books.id) AS book_count
    FROM students
    LEFT JOIN books ON books.StudentID = students.StudentID
    GROUP BY StudentID
    ORDER BY students.FullName ASC
    LIMIT 0, 30;
    

    【讨论】:

    • 这很好用,但它不会返回没有任何书籍的学生。
    • 我做了一个测试,如果没有,它会在 book_count 中返回 1。您可以将 COUNT(*) 替换为 COUNT(books.id),当它没有任何书籍时,它会放置一个 0 而不是 1
    • 实际上它按预期工作,比我原来的查询要快得多,但是没有书的学生被返回为拥有 1 本书而不是 0 本书。不过,谢谢。
    • 请阅读我之前的评论以修复没有书籍时的错误。如果有帮助,请将问题的答案标记为“已选择”
    猜你喜欢
    • 2015-06-21
    • 2014-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 2019-09-15
    • 1970-01-01
    相关资源
    最近更新 更多