Mysql 嵌套子查询太慢

Mysql 嵌套子查询太慢,mysql,sql,Mysql,Sql,以下使用双嵌套子查询的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 W

以下使用双嵌套子查询的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分钟后就放弃了

有什么方法可以优化它吗?

试试:

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';
仅使用联接编写的此版本将更快。

尝试:

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';

仅使用联接编写此版本会快得多。

尝试使用
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';
因此,您需要以下索引:

  • 术语(分类法,术语id)
  • 提供URL(提供术语id)
  • 术语关系(创造性的、术语的)
  • 创意人(创意id)

您可能已经使用主键定义定义了其中的一些。

请尝试使用
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';
因此,您需要以下索引:

  • 术语(分类法,术语id)
  • 提供URL(提供术语id)
  • 术语关系(创造性的、术语的)
  • 创意人(创意id)

您可能已经使用主键定义定义了其中的一些连接。

为什么不尝试
左外部连接
和空检查呢?虽然下一条语句纯粹是猜测,但我会假设每个检索到的行都执行子查询(因此,a行对所有b行执行子查询,b行分别对所有c行执行子查询)。您的表索引是否正确?为什么不尝试
左外部联接
和空检查呢?虽然下一条语句纯粹是猜测,但我假设每个检索到的行都会执行子查询(因此,a行对所有b行执行子查询,b行对所有c行执行子查询)。表的索引是否正确?您可能应该解释为什么可以省略where。。在里面部分:),但您的解决方案与我提出的相同。我在发布答案一分钟后对其进行了编辑,以添加
where
,但我在副本粘贴中遗漏了它。不幸的是,这种逻辑对我不起作用。对于每个offer\u term\u id,我在term\u relationships表中有许多记录。每条记录都会给我一个创意id。现在,我需要在term_relationships表中对每个创意id再次进行二次搜索。从该数据集中,我必须过滤需要分类的记录。我希望我在这里讲得有道理。对于一个人来说,不看表格就很难理解这一切。但是谢谢你的帮助。如果你还有其他建议,请告诉我。考虑拆分查询并让php处理一些logicHi@hvs,如果您能够提供数据示例(sql格式将是理想的)和预期结果,我将为您提供进一步的帮助。如果你这样做,我会写下你的疑问。谢谢@Gab的好意。我已经创建了一个非常基本和简单的数据库来解释我在sqlfiddle上的情况。是传递所需数据的my查询,是传递空数据集的your查询。希望这能给你一点启示。当然,在实际场景中,term_关系和creatives表都是巨大的,因此我的查询的处理时间是不可接受的。您可能应该解释一下为什么可以忽略where。。在里面部分:),但您的解决方案与我提出的相同。我在发布答案一分钟后对其进行了编辑,以添加
where
,但我在副本粘贴中遗漏了它。不幸的是,这种逻辑对我不起作用。对于每个offer\u term\u id,我在term\u relationships表中有许多记录。每条记录都会给我一个创意id。现在,我需要在term_relationships表中对每个创意id再次进行二次搜索。从该数据集中,我必须过滤需要分类的记录。我希望我在这里讲得有道理。对于一个人来说,不看表格就很难理解这一切。但是谢谢你的帮助。如果你还有其他建议,请告诉我。考虑拆分查询并让php处理一些logicHi@hvs,如果您能够提供数据示例(sql格式将是理想的)和预期结果,我将为您提供进一步的帮助。如果你这样做,我会写下你的疑问。谢谢@Gab的好意。我已经创建了一个非常基本和简单的数据库来解释我在sqlfiddle上的情况。是传递所需数据的my查询,是传递空数据集的your查询。希望这能给你一点启示。当然,在实际场景中,term_关系和creatives表都非常庞大,因此查询的处理时间是不可接受的