使用带有IN子句的嵌套子查询提高MySQL查询的性能
我想提高以下查询的性能使用带有IN子句的嵌套子查询提高MySQL查询的性能,mysql,sql,performance,Mysql,Sql,Performance,我想提高以下查询的性能 SELECT DISTINCT StringId FROM translations WHERE status = 1 AND TranslationId IN ( SELECT Max(TranslationId) FROM translations WHERE languageId = 2 AND TranslationId > 0 GROUP BY Stri
SELECT DISTINCT StringId
FROM translations
WHERE status = 1
AND TranslationId IN
(
SELECT Max(TranslationId)
FROM translations
WHERE languageId = 2
AND TranslationId > 0
GROUP BY StringId;
由于In子句,此查询当前将永远使用
下面的子查询
SELECT Max(TranslationId)
FROM translations
WHERE languageId = 2
AND TranslationId > 0
GROUP BY StringId;
返回16000行,带16000行的IN子句花费了这么长时间
我提出的一个改进的查询是
SELECT DISTINCT t1.StringId
FROM translations t1
INNER JOIN
(
SELECT Max(TranslationId) MaxTranslationId,
StringId
FROM translations
WHERE languageId = 2
AND TranslationId > 0
GROUP BY StringId
) t2 ON t1.StringId = t2.StringId
AND t1.TranslationId = t2.MaxTranslationId
WHERE status = 1;
我希望内部连接只返回与StringId和Max(TranslationId)匹配的行,就像使用In子句一样
如果这是一种正确的方法,有人能给我一个答案吗?以下是使用
不存在的另一种方法
:
SELECT DISTINCT t.StringId
FROM translations t
WHERE status = 1 AND
NOT EXISTS (select 1
from translations t2
where t2.languageId = 2 and
t2.StringId = t.StringId and
t2.translationId > t.translationId
) AND
EXISTS (select 1
from translations t2
where t2.languageId = 2 and
t2.StringId = t.StringId and
t2.translationId > 0
)
为了提高性能,您需要在翻译(StringId、languageId、translationId)
上建立索引。这消除了其中一个聚合,用索引查找代替它,这可能会更快
编辑:上面的方法应该有效。但是,这也可能相对有效:
SELECT DISTINCT StringId
FROM translations t
WHERE status = 1 AND
t.TranslationId = (SELECT Max(t2.TranslationId)
FROM translations t2
WHERE t2.languageId = 2 AND t2.TranslationId > 0 AND
t2.StringId = t.StringId
);
是MySQL还是SQL Server?挑一个。它们不一样。@Siyual我在标题中说MySQL:)@Mike谢谢编辑:)这看起来是正确的方法。
内部联接应能提供您正在查找的结果,并且速度更快。您的查询在StringId
上缺少别名,因此将生成错误。这个方法看起来还可以,但是可能会有一个更有效的版本。谢谢你的回答!你能详细说明一下如何消除最大聚集吗?我已经运行了两个查询,它们给出了不同的结果:(@CoderSpinoza…在表中是TranslationId
唯一的吗?还是对TranslationId,StringId
唯一的?@CoderSpinoza…非常有趣。我想我发现了这个问题。条件t2.TranslationId>0
有一个有趣的效果。您想过滤掉t2.TranslationId=0
的行,b但最初的查询并没有这样做。