[英]MYSQL (NOT IN) query is very slow
我不知道为什么这个查询需要45分钟才能给我结果
table1 = 831293行
table2 = 2000.000行
SELECT ID, name FROM table1 WHERE name not IN (SELECT name FROM table2 ) LIMIT 831293
my.cnf文件如下所示:
max_allowed_packet = 64M
innodb_buffer_pool_size = 8G
innodb_log_file_size = 256M
query_cache_type = 1
query_cache_limit = 1M
该选择非常昂贵,因为在最坏的情况下,对于表1中的每个记录,您都必须遍历表2中的2.000.000条记录。 我不是MySQL专家,但是在Oracle平台上,我会考虑为table2建立索引和表空间。
顺便说一句,LIMIT部分是没有用的。
你有名字索引吗?
如果必须每次循环遍历每行table2,则可以有效地循环遍历831293 * 200000行,这很多。
在名称上建立索引后,由于可以更轻松地在该索引中搜索名称,因此可以显着提高性能。 (可能甚至是O(1),因为可能会有一个哈希表)
您可以按照以下步骤进行操作
ALTER TABLE `table2` ADD INDEX (`name`)
我认为使用Exist会更快。
select Id,name from
(
select table1.ID as ID, table1.name as name
FROM table1 inner join table2
on table1.name=table2.name
)
WHERE not EXISTS
(
select 1
FROM table1 inner join table2
on table1.name=table2.name);
同意:(a)添加索引,并且(b)limit子句无用。
考虑一个“左外部联接”-它将带走“左”表中的所有行,即使“右”表中不存在联接值也是如此-然后您过滤掉不需要的“右”值。
就像是:
SELECT t1.ID, t1.name
FROM table1 t1 left outer join table2 t2
on t1.name = t2.name
where t2.name is null;
注意:上面的sql假定名称在t2中是唯一的,而在t1中不是唯一的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.