2010-09-05 17 views
8

我有两个数据库表:“地点”和“翻译”。地名的翻译由从“地方”,其不具备翻译到指定的语言又选择记录由:SQL:“NOT IN”子查询优化或替代

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

这个工作罚款7个000记录的地方,但坠毁时数翻译的达到5万此后,查询时间约10秒,并返回错误:

2006 - MySQL server has gone away

据我了解,主要的问题是这里的子查询返回结果很多,BU我怎么能解决这个问题,如果我需要选择所有尚未翻译的地点?

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

+1

不是一个答案,更多的建议,如果它仍然可能在您的项目阶段。当我有那些不断出现的“MySQL服务器已经消失”的错误出现时,我将我的应用程序移植到Postgresql。自从 – Hao 2010-09-05 11:00:19

回答

13

显而易见的替代:

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

应该有超过(translations.id, translations.lang)群集综合指数(复合装置:一个单一的指数超过多个字段,聚集装置:索引支配表的排序)。

+0

以来从未回头谢谢,这正是我所错过的。 – krn 2010-09-05 11:02:08

+0

@Kernius:你能比较一下这个变化给你带来的差异吗? (该指数非常重要!) – Tomalak 2010-09-05 11:03:26

+1

我曾经为这些领域编制过索引,但仍然存在这个问题,当我转向您的建议时,这个问题就会消失。 – krn 2010-09-05 11:10:20

0

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