2012-08-04 52 views
1

我有一個嵌套查詢嚴重的問題,我懷疑MySQL解釋爲相關的子查詢時,實際上它應該是不相關的。查詢跨越兩張表格,一張是產品清單,另一張是各個時間點的價格。我的目標是爲全部價格範圍高於特定值的產品返回每個價格記錄。我的查詢是這樣的:SQL嵌套查詢interpereted作爲相關的不正確

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行,所以我認爲它正在執行外部每行的內部查詢,這並不理想。我在內部和外部查詢中確實有相同的列,所以我認爲在上面的內部和外部以不同的方式對它們進行別名會修復它,但它不會。

關於這裏發生了什麼的任何想法?

回答

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不要將子查詢作爲相關查詢執行。

+0

完美!現在執行0.018s而不是150s! – TimD 2012-08-04 17:21:40