1

ネストされたクエリに重大な問題があります。実際には相関していないはずのMySQLが相関サブクエリとして解釈していると思われます。クエリは 2 つのテーブルにまたがっており、1 つは製品のリストで、もう 1 つはさまざまな時点での価格です。私の目的は、常に特定の値を超える価格帯を持つ製品の各価格レコードを返すことです。私のクエリは次のようになります。

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 の単純なリストを指定すると、外側のクエリも正常に機能します。ただし、それらを一緒に実行すると、クエリは〜1500行を返すのに〜3分かかるため、外側の行ごとに内側のクエリを実行していると思いますが、これは理想的ではありません. 内側と外側のクエリで列に同じエイリアスを付けたので、上記のように内側と外側で異なるエイリアスを付ければ修正されると思いましたが、そうではありませんでした。

ここで何が起こっているかについてのアイデアはありますか?

4

1 に答える 1

2

MySQL は、インデックスを使用してクエリを高速に実行できると考えるかもしれませんOP.id。最初に確認することは、統計が最新かどうかです。

where ... inを filtering として書き換えることができます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

もう 1 つのオプションは、一時テーブルを使用することです。サブクエリの結果を一時テーブルに格納し、それを結合します。これにより、MySQL はサブクエリを相関クエリとして実行しないように強制されます。

于 2012-08-04T16:15:00.513 に答える