为什么MySQL挂在这个简单的子查询上?

时间:2017-07-23 01:25:06

标签: mysql sql-update subquery query-optimization

我有这个简单的查询,它在大约5秒内运行并返回大约500条记录,但是为什么我尝试在复合语句中使用它,MySQL只是挂起

SELECT DISTINCT ARTIST_ID FROM WORK
    GROUP BY ARTIST_ID
    HAVING AVG(WORK_MILLIS_VIEWED) > 10

然而,下面的查询永远不会终止。根据进程列表,它只是创建一个临时表,即使它应该只比子查询稍长一些,因为艺术家表格很小。

SELECT ARTIST_NAME FROM ARTIST
    WHERE ARTIST_ID IN (SELECT DISTINCT ARTIST_ID
         FROM WORK GROUP BY ARTIST_ID
         HAVING AVG(WORK_MILLIS_VIEWED) > 10)

我犯了一个愚蠢的错误吗?数据库似乎没有做任何其他事情。

1 个答案:

答案 0 :(得分:1)

MySQL在WHERE子句中很难使用子查询。它通常决定多次运行子查询(对于每个与子查询比较的不同ARTIST_ID值一次),即使您知道并且我知道子查询不会更改。

解决方法是在FROM子句中运行子查询并加入它:

SELECT A.ARTIST_NAME 
FROM (
    SELECT ARTIST_ID FROM WORK 
    GROUP BY ARTIST_ID HAVING AVG(WORK_MILLIS_VIEWED) > 10
) AS T
JOIN ARTIST A ON A.ARTIST_ID = T.ARTIST_ID

这至少会运行子查询一次,并在连接到另一个表实例时将其存储在临时表中。

您还将受益于该列(ARTIST_ID, WORK_MILLIS_VIEWED)列中的索引。