为什么MySQL挂在这个简单的子查询上?
我有一个简单的查询,它运行大约5秒钟,返回大约500条记录,但是为什么我要在复合语句MySQL中使用它,这个问题还没有解决为什么MySQL挂在这个简单的子查询上?,mysql,sql-update,subquery,query-optimization,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 AR
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)
我犯了愚蠢的错误吗?数据库似乎没有做任何其他事情。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
这将至少运行子查询一次,并在子查询连接到另一个表实例时将其存储在临时表中
您还将受益于按此顺序排列的一对列的索引
(艺术家ID,作品\u MILLIS\u已查看)
。啊,我明白了,所以MySQL正在重复聚合查询,这大约需要500x5s-但我可以更改隔离级别,它就会消失。@awiebe-让我们知道隔离级别是否有这种效果。@Rick James-仔细看,似乎我可以更改隔离级别,因为我的数据库不活动,这对我的应用程序有效,但对其他应用程序不好。在这种情况下,最好的办法是在子查询表上获取一个锁。好的,最后,我使用了表锁,将统计数据拉入我的业务逻辑,然后将它们放回带有更新的Artister中。此操作对事务存储引擎不起作用,因此您最好暂时挂起事务—快速运行批处理作业、更新,然后解锁。