我有临时内存表A和B.每个包含1列整数值 我需要找到A中但不在B中的所有值。
问题在于它非常慢,因为(我认为)内存表使用哈希而不是有序键。
如何有效地执行它?目前我正在使用 SELECT val FROM tableA WHERE val NOT IN(SELECT val FROM tableB)
每个表的定义: CREATE TABLE tableA(val INT,PRIMARY KEY使用HASH(val))ENGINE = MEMORY;
答案 0 :(得分:1)
select
a.val
from
tableA a
left outer join tableB b on a.val = b.val
where
b.val is null;
对250K行进行的一些额外测试表明,它们之间并不多:
call load_test_data();
call test_memory_tables_hash(); -- 0:00:00.597
call test_memory_tables_hash(); -- 0:00:00.362
call load_test_data();
call test_memory_tables_btree(); -- 0:00:00.460
call test_memory_tables_btree(); -- 0:00:00.429
完整的测试脚本:
drop table if exists tableA;
create table tableA
(
val int unsigned not null primary key
)
engine=innodb;
drop table if exists tableB;
create table tableB
(
val int unsigned not null primary key
)
engine=innodb;
drop procedure if exists load_test_data;
delimiter #
create procedure load_test_data()
proc_main:begin
declare i int unsigned default 0;
declare rnd int unsigned default 0;
declare max int unsigned default 250000;
truncate table tableA;
truncate table tableB;
set autocommit = 0;
while i < max do
if i % 2 = 0 then insert into tableA values (i); end if;
if i % 3 = 0 then insert into tableB values (i); end if;
set i = i+1;
end while;
commit;
end proc_main #
delimiter ;
drop procedure if exists test_memory_tables_hash;
delimiter #
create procedure test_memory_tables_hash()
proc_main:begin
create temporary table mem_tableA
(
val int unsigned not null, index using hash(val)
)
engine=memory select val from tableA;
create temporary table mem_tableB
(
val int unsigned not null, index using hash(val)
)
engine=memory;
insert into mem_tableA select val from tableA;
insert into mem_tableB select val from tableB;
select
a.val
from
mem_tableA a
left outer join mem_tableB b on a.val = b.val
where
b.val is null
order by
a.val desc
limit 64;
drop temporary table if exists mem_tableA;
drop temporary table if exists mem_tableB;
end proc_main #
delimiter ;
delimiter ;
drop procedure if exists test_memory_tables_btree;
delimiter #
create procedure test_memory_tables_btree()
proc_main:begin
create temporary table mem_tableA
(
val int unsigned not null, index using btree(val)
)
engine=memory select val from tableA;
create temporary table mem_tableB
(
val int unsigned not null, index using btree(val)
)
engine=memory;
insert into mem_tableA select val from tableA;
insert into mem_tableB select val from tableB;
select
a.val
from
mem_tableA a
left outer join mem_tableB b on a.val = b.val
where
b.val is null
order by
a.val desc
limit 64;
drop temporary table if exists mem_tableA;
drop temporary table if exists mem_tableB;
end proc_main #
delimiter ;
call load_test_data();
call test_memory_tables_hash();
-- 0:00:00.597
call test_memory_tables_hash();
-- 0:00:00.362
call load_test_data();
call test_memory_tables_btree();
-- 0:00:00.460
call test_memory_tables_btree();
-- 0:00:00.429