为Tatoeba项目优化MySQL查询

为Tatoeba项目优化MySQL查询,mysql,optimization,Mysql,Optimization,我已经下载了,我正在尝试查询它们,但是带有子查询的查询花费的时间太长了 -- 800.000 rows approx. CREATE TABLE `sentences` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `language` char(3) DEFAULT NULL, `text` mediumtext, PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=912551

我已经下载了,我正在尝试查询它们,但是带有子查询的查询花费的时间太长了

-- 800.000 rows approx.
CREATE TABLE `sentences` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `language` char(3) DEFAULT NULL,
  `text` mediumtext,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=912551 DEFAULT CHARSET=utf8


-- 1.5 million rows approx.
CREATE TABLE `links` (
  `sentenceId` int(10) unsigned NOT NULL,
  `translatedId` int(10) unsigned NOT NULL,
  PRIMARY KEY (`sentenceId`,`translatedId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
基本上,链接表将
句子表中的两个句子连接在一起(原始句子和一个翻译)。一个句子可以有零个或多个翻译。所以我有一个我想处理的句子的id,我想获取所有可用的翻译

这个查询得到了我想要的东西,但几乎需要18秒才能完成。

SELECT * FROM `sentences` WHERE `id` IN (SELECT `translatedId` FROM `links` WHERE `sentenceId` = 157967);
单独运行这两个查询只需要一瞬间

我做错了什么?

试试这个(使用EXISTS子句):

如果translatedId在
链接中是唯一的
,则可以按如下所示进行内部联接

SELECT a.* 
    FROM `sentences` a INNER JOIN `links` b
      ON b.`translatedId`=a.`id`

众所周知,MySQL的某些版本在子查询中不使用索引。

嘿,谢谢,这很有效!你介意指出我做错了什么吗?@朱利安:你没做错什么。您的查询是100%正确的。问题是MySQL目前(希望在将来的版本中得到修复)不能很好地处理
中的一些查询。因此,我们必须检查编写相同查询的其他方法,使用Cybernate的
JOIN
EXISTS
版本,看看哪种方法处理数据更快。还有一个问题:表中有索引吗?如果有,是什么索引?索引在原始问题中很常见。他们很好。啊,我明白了!谢谢你的解释@虽然我的原始帖子有一个复合索引,但我尝试了使用所有可能的索引组合进行相同的查询,以获得相同的结果(有些甚至超过20秒!)
SELECT a.* 
    FROM `sentences` a INNER JOIN `links` b
      ON b.`translatedId`=a.`id`
SELECT `sentences`.* FROM 
  `sentences` JOIN 
  `links` ON `id` = `translatedId` 
WHERE `sentenceId` = 157967;