2014-07-15 127 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'的行,但是原來的查詢沒有這樣做。 –