2017-03-15 187 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)

您可能已经定义了一些使用这些主键定义。