2014-07-15 91 views
0

我想提高以下查询的性能。使用带IN子句的嵌套子查询提高MySQL查询的性能

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; 

收益16,000行,并与16,000行子句什么是这么长时间。

,我想出了一个改进的查询是

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)的行。

如果这是一个正确的方法来处理,有人可以给我一个答案吗?

+0

它是MySQL还是SQL Server?选一个。他们不一样。 – Siyual

+0

@Siyual我说的标题中的MySQL :) – CoderSpinoza

+0

@Mike感谢您的编辑:) – CoderSpinoza

回答

2

以下是使用NOT EXISTS另一种方法:

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 
       ) 

出于性能考虑,你想对translations(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 
         ); 
+0

感谢您的回答!您能否详细说明如何消除最大聚合?我已经运行了两个查询,并且他们给了我不同的结果:( – CoderSpinoza

+0

@CoderSpinoza ...表中的TranslationId是唯一的吗?或者是'TranslationId,StringId'是唯一的吗? –

+0

@CoderSpinoza ...非常有趣。我认为我发现了这个问题,条件't2.translationId> 0'有一个有趣的效果,你想过滤掉't2.translationId = 0'的行,但是原来的查询没有这样做。 –