SQL:“NOT IN”子查询优化或替代方案

时间:2010-09-05 10:52:18

标签: mysql subquery

我有两个数据库表:“places”和“translations”。地名的翻译是通过从“地点”中选择记录来完成的,这些记录还没有指定语言的翻译:

SELECT `id`, `name`
FROM `places`
WHERE `id` NOT IN (SELECT `place_id` FROM `translations` WHERE `lang` = 'en')

这可以很好地处理7 000个地方的记录,但是当翻译数量达到5 000时崩溃。从那时起,查询大约需要10秒并返回错误:

  

2006 - MySQL服务器已经消失

据我所知,这里的主要问题是子查询返回到很多结果,如果我需要选择所有尚未翻译的地方,我该如何解决呢?

我的计划B是在“places”表中创建一个新的布尔字段,称为“翻译”,并在每次更改语言时将其重置为“false” - 这将阻止子查询。但是,也许我可以修改当前的SQL语句并防止添加其他字段?

2 个答案:

答案 0 :(得分:13)

显而易见的替代方案:

SELECT
  `id`, `name`
FROM
  `places`
WHERE 
  NOT EXISTS (
    SELECT 1 FROM `translations` WHERE `id` = `places`.`id` AND `lang` = 'en'
  )

应该有(translations.id, translations.lang)上的聚簇复合索引(复合意味着:多个字段上的单个索引,聚簇意味着:索引控制表的排序方式)。

答案 1 :(得分:0)

在这种情况下,我认为最好的选择是进行2次单独的查询。将第一个结果存储在变量中并使用第二个。

相关问题