Pessoal,
O que é mais rápido, utilizar Exists ou IN em consultas SQL no Oracle? A resposta é: depende!
No exemplo abaixo crio uma tabela TB_IMPORTACAO e alimento esta tabela com: Objetos e seus respectivos tipos que foram criados no banco Oracle. Realizo o insert de uma massa de dados na mesma tabela de importação para teste.
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 SQL> SQL> create table tb_importacao as 2 select a.object_name, 3 a.object_type 4 from all_objects a; Table created SQL> SQL> begin 2 for x in 1..20 3 loop 4 insert into tb_importacao 5 select a.object_name, a.object_type from all_objects a; 6 end loop; 7 8 commit; 9 end; 10 / PL/SQL procedure successfully completed
Crio a tabela TB_CONTROLE com os objetos que já foram importados, tabela essa que será utilizada em nossa subconsulta. Esta tabela contem apenas os tipos dos objetos criados no banco, como: TABLE, VIEW, INDEX etc.
Em seguida realizo uma contagem nas duas tabelas para termos em mente a massa de dados que estamos trabalhando, temos:
TB_MPORTACAO com 4 milhões de registros
TB_CONTROLE com 236 mil registros. (Estes valores estão duplicados na base).
SQL> create table tb_controle as 2 select a.object_type 3 from all_objects a; Table created SQL> select count(*) from tb_importacao; COUNT(*) ---------- 4970931 SQL> select count(*) from tb_controle; COUNT(*) ---------- 236712
Realizamos agora o comparativo entre duas consultas, utilizando o IN e o EXISTS.
Identificamos neste primeiro caso que com a utilização do exists foi 25% mais rápido!
SQL> select count(*) 2 from tb_importacao a 3 where a.object_type in (select b.object_type 4 from tb_controle b); COUNT(*) ---------- 4970931 Executed in 1,218 seconds SQL> SQL> select count(*) 2 from tb_importacao a 3 where exists (select 1 4 from tb_controle b 5 where b.object_type = a.object_type); COUNT(*) ---------- 4970931 Executed in 0,968 seconds
Agora em outro teste, criamos a tabela TB_CONTROLE_32 que contem valores únicos dos tipos de objetos criados no banco onde utilizaremos em nossa subconsulta! Esta tabela tem apenas 32 registros e são distintos.
SQL> create table tb_controle_32 as 2 select distinct a.object_type 3 from all_objects a; Table created SQL> select count(*) from tb_controle_32; COUNT(*) ---------- 32
Realizamos agora o mesmo comparativo utilizando IN e EXISTS, porem, em nossa subconsulta a tabela de controle com 32 registros distintos.
SQL> select count(*) 2 from tb_importacao a 3 where a.object_type in (select b.object_type 4 from tb_controle_32 b); COUNT(*) ---------- 4970931 Executed in 1,015 seconds SQL> SQL> select count(*) 2 from tb_importacao a 3 where exists (select 1 4 from tb_controle_32 b 5 where b.object_type = a.object_type); COUNT(*) ---------- 4970931 Executed in 1,156 seconds
Neste ultimo caso com a utilização do IN foi mais rápido!
Em resumo sobre Exists X IN, podemos dizer:
Baixa quantidade registros na subconsulta ou listas de valores pequenas, o IN tende a ser melhor.
Valores(lista) únicos na subconsulta, o IN tende a ser melhor.
Alta quantidade de registros na subconsulta, o Exists tende a ser melhor.
Valores duplicados na subconsulta, o Exists tende a ser melhor.
O melhor sempre, TESTE!
Abraço,
Ronaldo
Nenhum comentário:
Postar um comentário