Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用带有IN子句的嵌套子查询提高MySQL查询的性能_Mysql_Sql_Performance - Fatal编程技术网

使用带有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但最初的查询并没有这样做。