Mysql 嵌套子查询太慢
以下使用双嵌套子查询的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
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表都非常庞大,因此查询的处理时间是不可接受的