[firebase-br] NOT EXISTS

Carlos H. Cantu listas em warmboot.com.br
Ter Jul 22 21:50:54 -03 2014


Continuo discordando da generalização que vc fez no email inicial,
sobre evitar usar NOT. A prova de que a performance nem sempre é
prejudicada eu já dei.

No exemplo que postei, a consulta realizada pelo Firebird será a mesma
tanto na query que usa NOT como na que não usa: em ambos os casos, ele
irá verificar se houve pelo menos uma nota emitida para o produto
dentro do período especificado. A negativa é aplicada sobre o
resultado.

O tempo de preparação da query, no meu exemplo, foi menor com o NOT do
que sem ele. A diferença no tempo de execução foi de 47ms, ou seja,
praticamente nada.

O ganho que vc se refere geralmente ocorre em consultas onde usaram
NOT IN e vc substitui por EXISTS, pela limitação do otimizador eu já
citei (e que consta no ReleaseNotes).

O perigo de generalizar é que muitos assumem como verdade absoluta
para todos os casos, portanto, é importante ficar claro que cada caso
é um caso.

[]s
Carlos H. Cantu
www.FireBase.com.br - www.firebirdnews.org
www.warmboot.com.br - blog.firebase.com.br

GS> Como eu disse, ou você perde tempo na précompilação ou perderá depois.

GS> O FB pode simplesmente ter invertido a sua querie ou usado um
GS> indice invertido, ou ainda um table scan,... enfim, o fato é que
GS> algo teve de ser processado para determinar o que fazer e um
GS> simples NOT pode ter acrescentando uma complexidade ao processo
GS> que poderia ter resultado num tempo maior se não fosse a intervenção do pré-compilador.
GS>  
GS> Não se trata de NOT EXIST, NOT IN,... trata-se do peso do NOT em equações com listas.
GS> Pode ser escovação de bits da minha parte, mas em todos os
GS> trabalhos de consultoria que faço onde a queixa é performance,
GS> troco os NOT EXIST por EXIST ou LEFT JOIN ou mudo a lógica a fim
GS> de facilitar para o compilador e tenho tido muitos resultados
GS> positivos, é obvio que em alguns casos não dá, mas a maioria dá.
GS> Estou falando apenas de subqueries.
GS>  Minha premissa é simplificar ao compilador, mesmo que no
GS> resultado no final, o ganho tenha sido desprezível.

GS> Eu não confundiria nunca NOT EXIST com NOT IN, este ultimo quando
GS> usado com subquery o parser poderia dizer 'tá errado sua anta...' que eu ficaria aliviado :)
GS>  

GS> ate+



GS> Em 22 de julho de 2014 17:38, Carlos H. Cantu
GS> <listas em warmboot.com.br> escreveu:
GS>  
GS>> Para um not atingir um alvo todos os elementos terão de ser
 GS>> resgatados, para um exist, o primeiro elemento encontrado é o
 GS>> suficiente para alvo estar completo.
 GS>> Não importa o plano escolhido, na mesma perspectiva a negação
 GS>> sempre será pior, seja na hora do resgate ou na pré-compilação onde determinará o plano.
 GS>>  Estou admirado em você não se lembrar disso.
GS>  
GS>  Vamos para a prática:
GS>  
GS>  /* Todos os produtos que tiveram notas emitidas a partir de 1.1.2010 */
GS>  select P.CODPROD
GS>  from PRODUTOS P
GS>  where exists(select *
GS>                   from NOTAS N
GS>                   join PRODNOTA PN on PN.ID_NUM = N.ID_NUM and PN.CODPROD = P.CODPROD
GS>                   where N.EMISSAO > '1.1.2010')
GS>  
GS>  e
GS>  
GS>  /* Todos os produtos que NÃO tiveram notas emitidas a partir de 1.1.2010 */
GS>  select P.CODPROD
GS>  from PRODUTOS P
GS>  where NOT exists(select *
GS>                   from NOTAS N
GS>                   join PRODNOTA PN on PN.ID_NUM = N.ID_NUM and PN.CODPROD = P.CODPROD
GS>                   where N.EMISSAO > '1.1.2010')
GS>  
GS>  
GS>  Ambos usaram o mesmo PLAN, tiveram a mesma performance e o mesmo número de leituras
GS>  (indexadas e não indexadas). Ou seja, o NOT aqui não prejudicou em
GS>  nada a performance.
GS>  
GS>  Como eu disse, não confunda NOT IN com NOT EXISTS, pois são coisas
GS>  diferentes dependendo de como forem usados.
GS>  

GS>  []s
GS>  Carlos H. Cantu
GS>  www.FireBase.com.br - www.firebirdnews.org
GS>  www.warmboot.com.br - blog.firebase.com.br
GS>  
 GS>> Para um not atingir um alvo todos os elementos terão de ser
 GS>> resgatados, para um exist, o primeiro elemento encontrado é o
 GS>> suficiente para alvo estar completo.
GS>  
 GS>> Não importa o plano escolhido, na mesma perspectiva a negação
 GS>> sempre será pior, seja na hora do resgate ou na pré-compilação onde determinará o plano.
 GS>>  Estou admirado em você não se lembrar disso.
 GS>> Não usei 'select first 1', usei 'select 1' porque simplesmente
 GS>> não preciso de nenhum campo, estou apenas testando a existência -
 GS>> em alguns RDBMS isso economiza bytes ao parser, provavelmente no FB também.
 GS>>
 GS>> Um cordial abraço,
GS>  





Mais detalhes sobre a lista de discussão lista