sexta-feira, 22 de maio de 2009

A Função EXISTS

A função EXISTS recebe como parâmetro um SELECT, e retorna um valor boolean, caso a query passada como parâmetro tenha registros correspondentes ou não.

A grande vantagem da utilização do EXISTS é que assim que o primeiro registro do select é encontrado, o query processor pára a execução da query. Esta funcionalidade pode ser bastante útil na substituição de subquerys implementadas dentro de um operador IN, que são os grandes "ladrões" de performance de implementações SQL.

Vejamos um exemplo:

create table #uf_sul(
uf varchar(2)
)

insert into #uf_sul (uf) values ('SC')
insert into #uf_sul (uf) values ('RS')
insert into #uf_sul (uf) values ('PR')

create table #tmp_pedido(
uf varchar(2),
vlrCompra numeric(10,2),
vlrDesconto numeric(10,2),
dtCompra datetime
)

insert into #tmp_pedido (UF,vlrCompra,vlrDesconto,dtCompra) values ('SC',100.32,10.32,'2008-04-26 13:56:34.950')
insert into #tmp_pedido (UF,vlrCompra,vlrDesconto,dtCompra) values ('SC',230.32,10.32,'2008-03-26 13:56:34.950')
insert into #tmp_pedido (UF,vlrCompra,vlrDesconto,dtCompra) values ('SP',450.32,10.32,'2008-02-26 13:56:34.950')
insert into #tmp_pedido (UF,vlrCompra,vlrDesconto,dtCompra) values ('SP',670.32,10.32,'2008-06-26 13:56:34.950')
insert into #tmp_pedido (UF,vlrCompra,vlrDesconto,dtCompra) values ('MG',780.32,10.32,'2008-08-26 13:56:34.950')
insert into #tmp_pedido (UF,vlrCompra,vlrDesconto,dtCompra) values ('MG',980.32,10.32,'2008-02-26 13:56:34.950')


Se houver a necessidade de listar todos os pedidos relacionados a região sul, podemos fazer a seguinte query:

select
uf,
vlrCompra,
vlrDesconto,
dtCompra
from
#tmp_pedido t
where uf in (select uf from #uf_sul)


No exemplo acima, temos poucos registros em #uf_sul, mas em determinadas situações podemos ter sub-querys com um grande número de registros que podem tornar nossa implementação demasiadamente lenta.

Estas situações, podem ser melhoradas com a utilização da função EXISTS. Vejamos um exemplo:

select
uf,
vlrCompra,
vlrDesconto,
dtCompra
from
#temp t
where exists(select 0 from #uf_sul u where t.uf=u.uf)



Algumas considerações são muito importantes:
  • Evite utilizar o EXISTS em comparações negativas (NOT EXISTS).
  • Não haverá uma grande diferença de performance caso a query esteja sendo executada em uma primary query, porém se o campo pesquisado for um campo não indexado, a diferença será significativa.

Nenhum comentário:

Postar um comentário

Leave your comment here!