为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;