我有两个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
的'nother edit:index_length
和SHOW TABLE STATUS
table data_length index_length
A 465380 435200
B 5177996 1344512
答案 0 :(得分:2)
您在OUTER JOIN中比较的两列的字符集不同。我不确定这是否是原因所以我测试并得到了这些结果:
SELECT A1
FROM A
LEFT JOIN B ON A1 = B1
WHERE B1 IS NULL
-- Table A..: 23258 rows, collation = utf8_general_ci
-- Table B..: 70041 rows, collation = latin1_swedish_ci
-- Time ....: I CANCELLED THE QUERY AFTER 20 MINUTES
-- Table A..: 23258 rows, collation = latin1_swedish_ci
-- Table B..: 70041 rows, collation = latin1_swedish_ci
-- Time ....: 0.187 sec
-- Table A..: 23258 rows, collation = utf8_general_ci
-- Table B..: 70041 rows, collation = utf8_general_ci
-- Time ....: 0.344 sec
解决方案:使两个表(或至少两列)的字符集相同。
答案 1 :(得分:1)
此查询将扫描表A的所有行,但如果您在B1上有索引,那么很可能它不会扫描表B:
select A1
from A
where not exists (
select *
from B
where B.B1 = A.A1
)
在运行此查询或原始查询之前,您可以尝试运行ANALYZE TABLE
以更新这些表的密钥分发信息:
ANALYZE TABLE A, B
如果这没有用,那么您可以尝试使用索引,例如:
select A1
from A ignore index (PRIMARY)
where not exists (
select *
from B force index (NewIndex1)
where B.B1 = A.A1
)
答案 2 :(得分:0)
似乎 A1 和 B1 是大型游艇。
您为 A1 和 B1
创建了索引
确保将它们编入索引!
SELECT A1
FROM A
WHERE A1 NOT IN (
SELECT B1 AS A1 From B;
)
答案 3 :(得分:0)
尝试此查询:
SELECT B1
FROM B
WHERE not B1 in (
select A1
from a
)
答案 4 :(得分:0)
如果我使用您的CREATE TABLES语句并在SELECT语句上运行EXPLAIN,我会得到以下结果:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE A index NULL PRIMARY 767 NULL 2 Using index
1 SIMPLE B index NULL NewIndex1 258 NULL 4 Using where; Using index
在我的MySQL版本(5.1.41)上,索引按预期使用,所以我认为这可能是MySQL中已经修复的错误,假设您的索引设置类似于发布的create table语句。您使用的是什么MySQL版本?