2010-10-14 3 views
0

J'ai des tables de mémoire temporaires A et B. chacune contient 1 colonne de valeurs entières Je dois trouver toutes les valeurs qui sont dans A mais Le problème est que c'est très lent en raison du fait (je pense) que les tables de mémoire utilisent des clés de hachage et non ordonnées.Mysql: Comment trouver tous les éléments du tableau A qui ne sont pas dans la table B pour les tables de mémoire

Comment puis-je l'exécuter efficacement? Actuellement, je suis en utilisant SELECT val DE tableA OU val NOT IN (SELECT val DE tableB)

La définition de chaque table: CREATE TABLE tableA (val INT, CLÉ PRIMAIRE EN UTILISANT HASH (val)) MOTEUR = mémoire;

+0

est-val indexé dans les deux tableaux? –

+0

Oui, les deux sont créés de la même manière – Nir

Répondre

1
select 
a.val 
from 
tableA a 
left outer join tableB b on a.val = b.val 
where 
b.val is null; 

quelques tests supplémentaires sur les lignes 250K révèle qu'il n'y a pas grand-chose entre eux:

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 

script test complet:

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 
Questions connexes