我遇到了一个嵌套查询的严重问题,我怀疑MySQL正在将其解释为相关子查询,而事实上它应该是不相关的。该查询跨越两个表,一个是产品列表,另一个是在不同时间点的价格。我的目标是返回价格范围高于某个值的产品的每个价格记录。我的查询如下:
SELECT oP.id, oP.title, oCR.price, oC.timestamp
FROM Crawl_Results AS oCR
JOIN Products AS oP
ON oCR.product = oP.id
JOIN Crawls AS oC
ON oCR.crawl = oC.id
WHERE oP.id
IN (
SELECT iP.id
FROM Products AS iP
JOIN Crawl_Results AS iCR
ON iP.id = iCR.product
WHERE iP.category =2
GROUP BY iP.id
HAVING (
MAX( iCR.price ) - MIN( iCR.price )
) >1
)
ORDER BY oP.id ASC
单独使用,内部查询执行正常并返回价格范围高于标准的产品的ID列表。如果我在IN子句中提供一个简单的id列表,外部查询也可以正常工作。然而,当我一起运行它们时,查询需要~3分钟才能返回~1500行,所以我认为它正在为外部的每一行执行内部查询,这是不理想的。我确实在内部和外部查询中列的别名相同,所以我认为在内部和外部中对它们进行不同的别名会修复它,但事实并非如此。
关于这里发生了什么的任何想法?
答案 0 :(得分:2)
MySQL可能认为它可以使用索引通过为每OP.id
运行一次来更快地执行查询。首先要检查的是your statistics are up to date。
您可以将where ... in
重写为过滤inner join
。这不太可能被“优化”寻求:
SELECT *
FROM Crawl_Results AS oCR
JOIN Products AS oP
ON oCR.product = oP.id
JOIN Crawls AS oC
ON oCR.crawl = oC.id
JOIN (
SELECT iP.id
FROM Products AS iP
JOIN Crawl_Results AS iCR
ON iP.id = iCR.product
WHERE iP.category =2
GROUP BY
iP.id
HAVING (MAX(iCR.price) - MIN(iCR.price)) > 1
) filter
ON OP.id = filter.id
另一种选择是使用临时表。您将子查询的结果存储在临时表中并加入其中。这实际上迫使MySQL不要将子查询作为相关查询来执行。