【发布时间】:2011-10-18 21:27:59
【问题描述】:
我有两个 MySQL 表 A 和 B。A 只包含一个 varchar 列(我们称之为一个 A1),大约有 23000 条记录。表 B(70000 条记录)有更多列,其中一列与表 A 中的 A1 对应(我们称其为 B1)。我想知道A中的哪些值不在B的对应列中,所以我使用:
SELECT A1
FROM A
LEFT JOIN B
ON A1 = B1
WHERE B1 IS NULL
A1 和 B1 列都定义了索引。这个查询仍然运行得很慢。我已经运行了解释,这是输出:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE A index \N PRIMARY 767 \N 23269 Using index
1 SIMPLE B ALL \N \N \N \N 70041 Using where; Not exists
更新:SHOW CREATE TABLE 用于两个表(更改了原始名称);
CREATE TABLE `A` (
`A1` varchar(255) NOT NULL,
PRIMARY KEY (`A1`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
CREATE TABLE `B` (
`col1` int(10) unsigned NOT NULL auto_increment,
`col2` datetime NOT NULL,
`col3` datetime default NULL,
`col4` datetime NOT NULL,
`col5` varchar(30) NOT NULL,
`col6` int(10) default NULL,
`col7` int(11) default NULL,
`col8` varchar(20) NOT NULL,
`B1` varchar(255) default NULL,
`col10` tinyint(1) NOT NULL,
`col11` varchar(255) default NULL,
PRIMARY KEY (`col1`),
KEY `NewIndex1` (`B1`)
) ENGINE=MyISAM AUTO_INCREMENT=70764 DEFAULT CHARSET=latin1
'另一个编辑:data_length 和 index_length 来自SHOW TABLE STATUS
table data_length index_length
A 465380 435200
B 5177996 1344512
【问题讨论】:
-
您是否对表格进行任何索引?
-
有趣的是,如果我“反转”这个,那么做一个 RIGHT JOIN,只有 WHERE A1 IS NULL 它完成得更快
-
您能否发布个人资料结果:
SET profiling=1; SELECT SQL_NO_CACHE A1 FROM A LEFT JOIN B ON A1 = B1 WHERE B1 IS NULL; SHOW PROFILE;... 这可以准确地告诉我们大部分时间都在使用哪个步骤。当我使用示例数据(20000 + 70000 行)测试上述查询时,我在 -
我现在正在运行它。唯一的问题是我的问题中发布的查询尚未完成.. EDIT;当您测试查询时,您是否使用 varchar 作为列类型?我有一种感觉,这是需要这么长时间的原因之一......
-
@Lex:两个表,每个表都有一个 varchar 列,索引,填充随机字符串,两个表中都存在 4k 个字符串。除了个人资料信息,请张贴这两个表的大约大小...是 MB 还是 GB?这以您无法想象的方式很重要。
标签: mysql sql query-optimization collation