SQL嵌套查询被解释为关联不正确

时间:2012-08-04 14:58:10

标签: mysql sql nested-queries

我遇到了一个嵌套查询的严重问题,我怀疑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行,所以我认为它正在为外部的每一行执行内部查询,这是不理想的。我确实在内部和外部查询中列的别名相同,所以我认为在内部和外部中对它们进行不同的别名会修复它,但事实并非如此。

关于这里发生了什么的任何想法?

1 个答案:

答案 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不要将子查询作为相关查询来执行。