2017-03-15 233 views
0

它使用雙嵌套子查詢以下MySQL查詢太慢嵌套子查詢太慢

SELECT t.name 
FROM creatives AS c 
INNER JOIN term_relationships AS tr ON tr.creative_id=c.creative_id 
INNER JOIN terms AS t ON t.term_id=tr.term_id 
WHERE c.creative_id IN 
    (SELECT creative_id 
    FROM term_relationships 
    WHERE term_id IN 
     (SELECT offer_term_id 
     FROM offer_urls)) 
AND t.taxonomy LIKE 'ad_network'; 

內部查詢

SELECT creative_id 
    FROM term_relationships 
    WHERE term_id IN 
     (SELECT offer_term_id 
     FROM offer_urls) 

極快(0.04秒),

但完整的查詢不會提供結果。等了5分鐘後我放棄了。

任何方式來優化?

+0

爲什麼不嘗試'LEFT OUTER JOIN'和一個空檢查呢?雖然下一個語句是純粹的猜測,但我假設每個檢索行都執行子查詢(因此,行a,對所有行b執行子查詢,它們針對所有行c單獨執行)。 – Rogue

+0

您的表格是否正確編制索引? –

回答

2

嘗試:

SELECT t.name 
FROM creatives AS c 
JOIN term_relationships AS tr ON tr.creative_id=c.creative_id 
JOIN terms AS t ON t.term_id=tr.term_id 
JOIN term_relationships tr2 ON tr2.creative_id = c.creative_id 
JOIN offer_urls ou ON ou.offer_term_id = tr2.term_id 
WHERE t.taxonomy LIKE 'ad_network'; 

此版本僅使用連接將更快寫的。

+0

你也許應該解釋爲什麼你可以離開的地方..在..部分:),但你的解決方案是一樣的我想出了 – r3bel

+0

我編輯答案一分鐘後發佈它添加'哪裏',我錯過了它在複製粘貼 – Gab

+0

不幸的是,這種邏輯不適合我。對於每個offer_term_id,我在term_relationships表中有許多記錄。每條記錄都會給我一個creative_id。現在,我需要再次使用term_relationships表中的每個creative_id進行輔助搜索。從該數據集中,我將不得不篩選需要分類的記錄。我希望我在這裏有所幫助。有人不看桌子就很難理解這一切。但是,謝謝你的幫助。如果您有其他建議,請告訴我。想分裂查詢,並讓PHP處理一些邏輯 – hvs

0

嘗試重寫此使用exists

SELECT t.name 
FROM terms t JOIN 
    term_relationships tr 
    ON t.term_id = tr.term_id JOIN 
    creatives c 
    ON tr.creative_id = c.creative_id 
WHERE EXISTS (SELECT 1 
       FROM term_relationships tr2 JOIN 
        offer_urls ou 
        ON tr.term_id = ou.offer_term_id 
       WHERE c.creative_id = tr2.creative_id 
      ) AND 
    t.taxonomy LIKE 'ad_network'; 

那麼對於這一點,你希望達到以下指標:

  • 條款(分類,term_id)
  • offer_urls(offer_term_id)
  • term_relationships( creative_id,term_id);
  • 廣告(CREATIVE_ID)

您可能已經定義了一些使用這些主鍵定義。