MySQL - SELECT WHERE field IN(子查询) - 为什么非常慢?
我想检查数据库中有几个重复项,所以我做了什么来查看哪些是重复项,我这样做了:
I've got a couple of duplicates in a database that I want to inspect, so what I did to see which are duplicates, I did this:
SELECT relevant_field
FROM some_table
GROUP BY relevant_field
HAVING COUNT(*) > 1
这样,我将获得相关字段出现不止一次的所有行.此查询需要几毫秒才能执行.
This way, I will get all rows with relevant_field occuring more than once. This query takes milliseconds to execute.
现在,我想检查每个重复项,所以我想我可以在上面的查询中使用相关字段选择 some_table 中的每一行,所以我这样做了:
Now, I wanted to inspect each of the duplicates, so I thought I could SELECT each row in some_table with a relevant_field in the above query, so I did like this:
SELECT *
FROM some_table
WHERE relevant_field IN
(
SELECT relevant_field
FROM some_table
GROUP BY relevant_field
HAVING COUNT(*) > 1
)
由于某种原因,这变得非常缓慢(需要几分钟).这里到底发生了什么让它变得这么慢?相关字段已编入索引.
This turns out to be extreeeemely slow for some reason (it takes minutes). What exactly is going on here to make it that slow? relevant_field is indexed.
最终我尝试从第一个查询(SELECT related_field FROM some_table GROUP BY related_field HAVING COUNT(*) > 1)
创建一个视图temp_view",然后像这样进行我的第二个查询:
Eventually I tried creating a view "temp_view" from the first query (SELECT relevant_field FROM some_table GROUP BY relevant_field HAVING COUNT(*) > 1)
, and then making my second query like this instead:
SELECT *
FROM some_table
WHERE relevant_field IN
(
SELECT relevant_field
FROM temp_view
)
而且效果很好.MySQL 会在几毫秒内完成此操作.
And that works just fine. MySQL does this in some milliseconds.
这里有没有 SQL 专家可以解释发生了什么?
Any SQL experts here who can explain what's going on?
推荐答案
正在为每一行运行子查询,因为它是一个相关查询.通过从子查询中选择所有内容,可以将相关查询变成非相关查询,如下所示:
The subquery is being run for each row because it is a correlated query. One can make a correlated query into a non-correlated query by selecting everything from the subquery, like so:
SELECT * FROM
(
SELECT relevant_field
FROM some_table
GROUP BY relevant_field
HAVING COUNT(*) > 1
) AS subquery
最终查询将如下所示:
SELECT *
FROM some_table
WHERE relevant_field IN
(
SELECT * FROM
(
SELECT relevant_field
FROM some_table
GROUP BY relevant_field
HAVING COUNT(*) > 1
) AS subquery
)
相关文章