Re: [oracle_br] Re: USANDO 'OR' NO FILTRO

2013-07-23 Por tôpico Elcio Francisco
Eu entendo amigo Chiappa te agradeço por sempre esta nos ajudando, o que você 
diz e te agradeço mas minha duvida é sobre essa parte destacada do filtro

select count(distinct mov.numero_venda) qtd
                                                  ,sum(gar.saldo_devedor) 
total_saldo
                                                  ,loj.unidade_servico
                                     from crd.loja      loj                     
                    
                                         ,crd.garantia  gar
                                         ,crd.cliente   cli
                                         ,crd.movimento mov                     
                              
                                     where loj.regional LIKE DECODE(p_regional, 
'0', '%','%' || p_regional || '%') 
                                       and loj.filial LIKE DECODE(p_filial, 
'0', '%','%' || p_filial || '%')
                                       and loj.escritorio    = p_escritorio  
                                       and loj.grupo         = p_cliente
                                       and loj.regional       'T0'
                                       and loj.filial         'T0'
                                       and loj.identificacao = '1'
                                       and loj.empresa       = 
cli.empresa_origem
                                       and cli.cliente       = gar.cliente
                                       and cli.empresa       = gar.empresa 
                                       and gar.flg_garantia  = 'P'  
                                       and gar.dt_naoconfirmacao is not null 

                                       and (((gar.dt_confirmacao_documento is 
not null) and trunc(gar.dt_confirmacao_documento) = p_primeiro_dia) or
                                           ((gar.dt_confirmacao_documento is 
null)      and trunc(gar.dt_vencimento)       = p_primeiro_dia))
                                       and (((gar.dt_confirmacao_documento is 
not null) and trunc(gar.dt_confirmacao_documento) = p_ultimo_dia) or
                                           ((gar.dt_confirmacao_documento is 
null)      and trunc(gar.dt_vencimento)       = p_ultimo_dia))                 
                  

                                       and gar.numero_venda = mov.numero_venda  
                                
                                       and mov.operacao = '01'
                                       and mov.produto LIKE DECODE(p_produto, 
'0', '%','%' || p_produto || '%') 
                                       and mov.loja_empresa = loj.empresa
                                       and mov.loja_central = loj.central
                                       and mov.loja_loja = loj.loja             
                          
                                       group by loj.unidade_servico             
                       
                                       order by loj.unidade_servico 

Elcio Francisco 





 De: J. Laurindo Chiappa jlchia...@yahoo.com.br
Para: oracle_br@yahoogrupos.com.br 
Enviadas: Terça-feira, 23 de Julho de 2013 15:40
Assunto: [oracle_br] Re: USANDO 'OR' NO FILTRO
 


  
Bom, primeiro eu ** TENHO ** que dizer que alguém que diz, point-blank e 
generalizando, que X deixa lento, SEM dizer o porque, SEm testes/provas/caso 
repetível, para mim está usando regras de dedão for a de contexto, está é 
ESPALHANDO MITOS, falando abobrinha, okdoc ?? É algo semelhante aos tantos 
outros mitos de performance, tipo EXISTS é melhor/pior que IN - afirmações 
extraordinárias exigem provas extraordinárias Pra  mim afirmação sem prova 
é a indicação CLARA que o sujeito é um dba, entre aspas e minúsculas 
totais

Isso posto, a sua resposta - se por qquer motivo vc não quiser usar o NULL, sem 
analisar muito, eu ACHO que com :

and (loj.fim_atividade is null or gar.dt_vencimento  loj.fim_atividade) 

vc quer que se loj.fim_atividade for null NADA SEJA COMPARADO (o mesmo efeito 
que vc fazer uma comparação sempre verdadeira), e que quando loj.fim_atividade 
NÃO for null aí sim a comparação deve ser feita com gar.dt_vencimento  
loj.fim_atividade  Sabendo (como já comentado em outra thread recentemente) 
que uma das possibilidades ao se lidar com NULL é o NVL, poderíamos usar :

and gar.dt_vencimento  nvl(loj.fim_atividade, to_date('31/12/', 
'dd/mm/') )


ok ? A linha acima é praticamente a tradução do que eu disse em português : 
SE fim_atividade for null o valor retornado pelo NVL é um valor que  
necessariamente é maior que dt_vencimento, portanto sempre sendo verdadeira, E 
SE fim_atividade for não-nulo, aí a comparação é dt_vencimento  
loj.fim_atividade , como desejado, acho eu

[]s

Chiappa

--- Em oracle_br@yahoogrupos.com.br, Elcio Francisco elciofrancisco@... 
escreveu

 Pessoal, os dba´s sempre fala que no filtro quando tem a clausula OR deixa 
 lento. Nesse caso testo se data

Re: [oracle_br] Re: USANDO 'OR' NO FILTRO

2013-07-23 Por tôpico Fabio Prado
Chiappa,

  O item do EXISTS ser melhor ou pior do que o IN não é mito! Existe uma
regra para usar um ou outro (que em alguns casos pode melhorar o plano de
execução), que está documentada no Oracle Performance Tuning Guide, veja:
http://docs.oracle.com/cd/B19306_01/server.102/b14211/sql_1016.htm


Elcio,

   Algumas dicas gerais, para melhorar performance, evite o uso de OR,
comparações com NULL e funções nas instruções SQL. Se não for possível
evitá-las existem algumas formas de contornar a má performance que isso
tudo iria gerar, mas tudo isso não é muito simples e exige muitos
conhecimentos prévios que não dá para explicar aqui (eu ensino em
treinamentos SQL Tuning).

[]s

Fábio Prado
http://www.fabioprado.net


Em 23 de julho de 2013 15:40, J. Laurindo Chiappa
jlchia...@yahoo.com.brescreveu:

 **


 Bom, primeiro eu ** TENHO ** que dizer que alguém que diz, point-blank e
 generalizando, que X deixa lento, SEM dizer o porque, SEm
 testes/provas/caso repetível, para mim está usando regras de dedão for a de
 contexto, está é ESPALHANDO MITOS, falando abobrinha, okdoc ?? É algo
 semelhante aos tantos outros mitos de performance, tipo EXISTS é
 melhor/pior que IN - afirmações extraordinárias exigem provas
 extraordinárias Pra mim afirmação sem prova é a indicação CLARA que o
 sujeito é um dba, entre aspas e minúsculas totais

 Isso posto, a sua resposta - se por qquer motivo vc não quiser usar o
 NULL, sem analisar muito, eu ACHO que com :


 and (loj.fim_atividade is null or gar.dt_vencimento  loj.fim_atividade)

 vc quer que se loj.fim_atividade for null NADA SEJA COMPARADO (o mesmo
 efeito que vc fazer uma comparação sempre verdadeira), e que quando
 loj.fim_atividade NÃO for null aí sim a comparação deve ser feita com
 gar.dt_vencimento  loj.fim_atividade  Sabendo (como já comentado em
 outra thread recentemente) que uma das possibilidades ao se lidar com NULL
 é o NVL, poderíamos usar :

 and gar.dt_vencimento  nvl(loj.fim_atividade, to_date('31/12/',
 'dd/mm/') )


 ok ? A linha acima é praticamente a tradução do que eu disse em
 português : SE fim_atividade for null o valor retornado pelo NVL é um valor
 que necessariamente é maior que dt_vencimento, portanto sempre sendo
 verdadeira, E SE fim_atividade for não-nulo, aí a comparação é
 dt_vencimento  loj.fim_atividade , como desejado, acho eu

 []s

 Chiappa

 --- Em oracle_br@yahoogrupos.com.br, Elcio Francisco elciofrancisco@...
 escreveu

 
  Pessoal, os dba´s sempre fala que no filtro quando tem a clausula OR
 deixa lento. Nesse caso testo se data dt_confirmacao_documento for null ele
 busca pela data gar.dt_vencimento
  como fazer isso sem usar o OR
 
  Muito obrigado
 
  select count(distinct mov.numero_venda)
 qtd
   ,sum(gar.saldo_devedor)
 total_saldo
   ,loj.unidade_servico
   from crd.empresa  loj
   ,crd.cliente   cli
   ,crd.vendas  gar
   ,crd.pedido mov

   where loj.regional LIKE
 DECODE(p_regional, '0', '%','%' || p_regional || '%')
 and loj.filial LIKE
 DECODE(p_filial, '0', '%','%' || p_filial || '%')
 and loj.escritorio = p_escritorio

 and loj.grupo = p_cliente
 and loj.regional  'T0'
 and loj.filial'T0'
 and loj.identificacao = '1'
 and loj.empresa  =
 cli.empresa_origem
 and cli.cliente = gar.cliente
 and cli.empresa = gar.empresa
 and gar.flg_garantia = 'P'
 and (((dt_confirmacao_documento
 is not null) and trunc(dt_confirmacao_documento) = p_primeiro_dia) or
 ((dt_confirmacao_documento is
 null)  and trunc(gar.dt_vencimento)   = p_primeiro_dia))
 and (((dt_confirmacao_documento
 is not null) and trunc(dt_confirmacao_documento) = p_ultimo_dia) or
 ((dt_confirmacao_documento is
 null)  and trunc(gar.dt_vencimento)   = p_ultimo_dia))

 and gar.numero_venda =
 mov.numero_venda
 and mov.operacao = '01'
 and mov.produto LIKE
 DECODE(p_produto, '0', '%','%' || p_produto || '%')
 and mov.loja_empresa = loj.empresa
 

Re: [oracle_br] Re: USANDO 'OR' NO FILTRO

2013-07-23 Por tôpico Milton Bastos Henriquis Jr.
Estou super enferrujado em SQL, parei de trabalhar com Oracle, mas...

Confiram se não dá pra trocar isso:

 (((gar.dt_confirmacao_documento is not null) and
trunc(gar.dt_confirmacao_documento)
= p_primeiro_dia) or
   ((gar.dt_confirmacao_documento
is null)  and trunc(gar.dt_vencimento)   = p_primeiro_dia))


Por isso:

DECODE(gar.dt_confirmacao_documento, null, trunc(gar.dt_vencimento),
trunc(gar.dt_confirmacao_documento)) = p_primeiro_dia




2013/7/23 Elcio Francisco elciofranci...@yahoo.com.br

 **


 Eu entendo amigo Chiappa te agradeço por sempre esta nos ajudando, o que
 você diz e te agradeço mas minha duvida é sobre essa parte destacada do
 filtro


 select count(distinct mov.numero_venda) qtd
   ,sum(gar.saldo_devedor)
 total_saldo
   ,loj.unidade_servico
  from crd.loja  loj

  ,crd.garantia  gar
  ,crd.cliente   cli
  ,crd.movimento mov


  where loj.regional LIKE
 DECODE(p_regional, '0', '%','%' || p_regional || '%')
and loj.filial LIKE
 DECODE(p_filial, '0', '%','%' || p_filial || '%')
and loj.escritorio=
 p_escritorio
and loj.grupo = p_cliente
and loj.regional   'T0'
and loj.filial 'T0'
and loj.identificacao = '1'
and loj.empresa   =
 cli.empresa_origem
and cli.cliente   = gar.cliente
and cli.empresa   = gar.empresa
and gar.flg_garantia  = 'P'
and gar.dt_naoconfirmacao is not
 null

and (((gar.dt_confirmacao_documento
 is not null) and trunc(gar.dt_confirmacao_documento) = p_primeiro_dia) or
((gar.dt_confirmacao_documento
 is null)  and trunc(gar.dt_vencimento)   = p_primeiro_dia))
and (((gar.dt_confirmacao_documento
 is not null) and trunc(gar.dt_confirmacao_documento) = p_ultimo_dia) or
((gar.dt_confirmacao_documento
 is null)  and trunc(gar.dt_vencimento)   = p_ultimo_dia))



and gar.numero_venda =
 mov.numero_venda
and mov.operacao = '01'
and mov.produto LIKE
 DECODE(p_produto, '0', '%','%' || p_produto || '%')
and mov.loja_empresa = loj.empresa
and mov.loja_central = loj.central
and mov.loja_loja = loj.loja

group by loj.unidade_servico

order by loj.unidade_servico

 Elcio Francisco

 
 De: J. Laurindo Chiappa jlchia...@yahoo.com.br
 Para: oracle_br@yahoogrupos.com.br
 Enviadas: Terça-feira, 23 de Julho de 2013 15:40
 Assunto: [oracle_br] Re: USANDO 'OR' NO FILTRO




 Bom, primeiro eu ** TENHO ** que dizer que alguém que diz, point-blank e
 generalizando, que X deixa lento, SEM dizer o porque, SEm
 testes/provas/caso repetível, para mim está usando regras de dedão for a de
 contexto, está é ESPALHANDO MITOS, falando abobrinha, okdoc ?? É algo
 semelhante aos tantos outros mitos de performance, tipo EXISTS é
 melhor/pior que IN - afirmações extraordinárias exigem provas
 extraordinárias Pra mim afirmação sem prova é a indicação CLARA que o
 sujeito é um dba, entre aspas e minúsculas totais

 Isso posto, a sua resposta - se por qquer motivo vc não quiser usar o
 NULL, sem analisar muito, eu ACHO que com :

 and (loj.fim_atividade is null or gar.dt_vencimento  loj.fim_atividade)

 vc quer que se loj.fim_atividade for null NADA SEJA COMPARADO (o mesmo
 efeito que vc fazer uma comparação sempre verdadeira), e que quando
 loj.fim_atividade NÃO for null aí sim a comparação deve ser feita com
 gar.dt_vencimento  loj.fim_atividade  Sabendo (como já comentado em
 outra thread recentemente) que uma das possibilidades ao se lidar com NULL
 é o NVL, poderíamos usar :

 and gar.dt_vencimento  nvl(loj.fim_atividade, to_date('31/12/',
 'dd/mm/') )

 ok ? A linha acima é praticamente a tradução do que eu disse em
 português : SE fim_atividade for null o valor retornado pelo NVL é um valor
 que necessariamente é maior que dt_vencimento, portanto sempre

Re: [oracle_br] Re: USANDO 'OR' NO FILTRO

2013-07-23 Por tôpico Fabio Prado
Perfeito Chiappa! Agora concordo com você!

Tem muita coisa em Tuning que não tem regra absoluta. Os casos tem que ser
analisados e testados. Eu mostro nos meus treinamentos de SQL Tuning que em
certas situações utilizar o CASE para evitar múltiplas instruções com UNION
ALL melhora a performance. Em outras eu faço o contrário e consigo melhorar
também a performance, mudando um pouco o jeito de escrever a instrução SQL.
Mostro várias situações parecidas com essa, através de teoria e prática!

Existem muitas variantes que influenciam na performance, portanto, aviso ao
pessoal que está iniciando estudos em tuning: *Não há RECEITA DE BOLO que
serve para OTIMIZAR qq instrução SQL e nem para otimizar qualquer instância
de BD*! Há muita coisa a ser estudada para entender quando e como fazer!

[]s

Fábio Prado
http://www.fabioprado.net




Em 23 de julho de 2013 16:44, J. Laurindo Chiappa
jlchia...@yahoo.com.brescreveu:

 **


 O mito, como eu disse, é a GENERALIZAÇÂO : afirmar que x é melhor que y
 SEM indicar especifidades, sem ter uma análise/prova, SEM se levar em conta
 que há ocasiões/situações em que x pode ser pior MAS há também situações em
 que x pode ser MUITO MELHOR, é sim folclore de DBAs : diversos
 especialistas Reconhecidos (
 http://asktom.oracle.com/pls/asktom/f?p=100:11:0P11_QUESTION_ID:953229842074#1525158235153é
  um exemplo) já fizeram a prova de que Há situações em que EXISTS pode ser
 nelhor mas há também situações em que ele pode ser pior O MITO, repito,
 é afirmar point-blank algo, SEM prova/referência/demonstração...
 Isso vale também para o caso do colega : DE FORMA ALGUMA se pode afirmar
 que SEMPRE o OR causa piora ou melhora na performance, quem manda uma
 firmação dessa generalizada E sem demonstração/restrição sorry, mas só pode
 estar espalhando uma historinha que ouviu , algo que ele ACHA que é assim,
 uma regrinha geral que ele não sabe como/se/aonde funciona ou se funciona,
 , ou seja, um mito...

 []s

 Chiappa
 --- Em oracle_br@yahoogrupos.com.br, Fabio Prado fbifabio@... escreveu
 
  Chiappa,
 
  O item do EXISTS ser melhor ou pior do que o IN não é mito! Existe uma
  regra para usar um ou outro (que em alguns casos pode melhorar o plano de
  execução), que está documentada no Oracle Performance Tuning Guide, veja:
  http://docs.oracle.com/cd/B19306_01/server.102/b14211/sql_1016.htm
 
 
  Elcio,
 
  Algumas dicas gerais, para melhorar performance, evite o uso de OR,
  comparações com NULL e funções nas instruções SQL. Se não for possível
  evitá-las existem algumas formas de contornar a má performance que isso
  tudo iria gerar, mas tudo isso não é muito simples e exige muitos
  conhecimentos prévios que não dá para explicar aqui (eu ensino em
  treinamentos SQL Tuning).
 
  []s
 
  Fábio Prado
  http://www.fabioprado.net
 
 
  Em 23 de julho de 2013 15:40, J. Laurindo Chiappa
  jlchiappa@...escreveu:
 
   **
  
  
   Bom, primeiro eu ** TENHO ** que dizer que alguém que diz, point-blank
 e
   generalizando, que X deixa lento, SEM dizer o porque, SEm
   testes/provas/caso repetível, para mim está usando regras de dedão for
 a de
   contexto, está é ESPALHANDO MITOS, falando abobrinha, okdoc ?? É algo
   semelhante aos tantos outros mitos de performance, tipo EXISTS é
   melhor/pior que IN - afirmações extraordinárias exigem provas
   extraordinárias Pra mim afirmação sem prova é a indicação CLARA
 que o
   sujeito é um dba, entre aspas e minúsculas totais
  
   Isso posto, a sua resposta - se por qquer motivo vc não quiser usar o
   NULL, sem analisar muito, eu ACHO que com :
  
  
   and (loj.fim_atividade is null or gar.dt_vencimento 
 loj.fim_atividade)
  
   vc quer que se loj.fim_atividade for null NADA SEJA COMPARADO (o mesmo
   efeito que vc fazer uma comparação sempre verdadeira), e que quando
   loj.fim_atividade NÃO for null aí sim a comparação deve ser feita com
   gar.dt_vencimento  loj.fim_atividade  Sabendo (como já comentado
 em
   outra thread recentemente) que uma das possibilidades ao se lidar com
 NULL
   é o NVL, poderíamos usar :
  
   and gar.dt_vencimento  nvl(loj.fim_atividade, to_date('31/12/',
   'dd/mm/') )
  
  
   ok ? A linha acima é praticamente a tradução do que eu disse em
   português : SE fim_atividade for null o valor retornado pelo NVL é um
 valor
   que necessariamente é maior que dt_vencimento, portanto sempre sendo
   verdadeira, E SE fim_atividade for não-nulo, aí a comparação é
   dt_vencimento  loj.fim_atividade , como desejado, acho eu
  
   []s
  
   Chiappa
  
   --- Em oracle_br@yahoogrupos.com.br, Elcio Francisco elciofrancisco@
   escreveu
  
   
Pessoal, os dba´s sempre fala que no filtro quando tem a clausula OR
   deixa lento. Nesse caso testo se data dt_confirmacao_documento for
 null ele
   busca pela data gar.dt_vencimento
como fazer isso sem usar o OR
   
Muito obrigado
   
select count(distinct mov.numero_venda)
   qtd
,sum(gar.saldo_devedor)
   total_saldo