Re: [oracle_br] Re: USANDO 'OR' NO FILTRO
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
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
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
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