为什么这个查询运行得这么慢?
我有两个 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
UPDATE: 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
'另一个编辑:SHOW TABLE STATUS
中的 data_length
和 index_length
table data_length index_length
A 465380 435200
B 5177996 1344512
I have two MySQL tables say A and B. A contains just one varchar column (lets call that one A1) with about 23000 records. Table B (70000 records) has some more columns, one of the corresponding with A1 from table A (lets call that one B1). I want to know which values in A are not in the corresponding column in B, so I use:
SELECT A1
FROM A
LEFT JOIN B
ON A1 = B1
WHERE B1 IS NULL
Both columns A1 and B1 have indices defined on them. Still this query runs very slow. I've run explain, this is the output:
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
UPDATE: SHOW CREATE TABLE
for both tables (changed the original names);
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
'nother edit: data_length
and index_length
from SHOW TABLE STATUS
table data_length index_length
A 465380 435200
B 5177996 1344512
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您在 OUTER JOIN 中比较的两列的字符集不同。我不确定是否是这个原因,所以我测试并得到了这些结果:
解决方案:使两个表(或至少两列)的字符集相同。
The character sets of the two columns that you are comparing in an OUTER JOIN differ. I am not sure if this is the cause so I tested and got these results:
Solution: make the character sets of the two tables (or the two columns atleast) same.
此查询将扫描表 A 的所有行,但如果您在 B1 上有索引,那么它很可能不会扫描表 B:
在运行此查询或原始查询之前,您可以尝试在以下位置运行 ANALYZE TABLE为了更新这些表的密钥分布信息:
如果这没有帮助,那么您可以尝试使用索引,例如:
This query will scan all rows of table A, but if you have an index on B1 then most likely it will not scan table B:
Before running this or your original query you may try to run
ANALYZE TABLE
in order to update key distribution information for those tables:If this doesn't help then you can try to play with indexes, for instance:
看起来A1和B1是很大的领域。
请确保它们已建立索引!
It seems A1 and B1 are large feilds.
Make sure that they are indexed!
如果我使用您的 CREATE TABLES 语句并在您的 SELECT 语句上运行 EXPLAIN,我会得到以下结果:
在我的 MySQL 版本(5.1.41)上,索引按预期使用,所以我认为这可能是 MySQL 中已经修复的错误,假设您的索引设置就像您发布的创建表语句中一样。你使用什么版本的MySQL?
If I use your CREATE TABLES statements and run an EXPLAIN on your SELECT statement, I get this result:
On my MySQL version (5.1.41) the index is used as expected, so I think this might be an already fixed bug in MySQL assuming your index is set like in your create table statement posted. What MySQL version do you use?
尝试这个查询:
try this query: