Pular para o conteúdo
  • Este tópico contém 1 resposta, 2 vozes e foi atualizado pela última vez 7 anos, 11 meses atrás por Avatar photoJosé Laurindo Chiappa.
Visualizando 2 posts - 1 até 2 (de 2 do total)
  • Autor
    Posts
  • #108554
    Avatar de Fernando NuñezFernando Nuñez
    Participante

      Olá gostaria de uma ajuda na query abaixo, pois se trago um dado selecionado ele traz rapidamente, porém quando peço para trazer de todo um dia fica muito tempo e na verdade nem sei se ele vai trazer a informação pois sempre o interrompo por me cansar de esperar.

      A Query é a seguinte:

      select distinct
      (select ep.db_edii_comprador from db_edi_pedprod ep where ep.db_edii_comprador = ‘7895000000001’ and ep.db_edii_nro = pe.db_ped_ord_compra and rownum = 1) as Comprador,
      cedi.db_clied_codigo,
      (select cl.db_cli_nome from db_cliente cl where cl.db_cli_codigo = cedi.db_clied_codigo and cedi.db_clied_codigo = pe.db_ped_cliente and cl.db_cli_vinculo = 20374) as NomeCliente,
      edp.db_edip_empresa,
      pe.db_ped_dt_emissao,
      (select ep.db_edii_nro from db_edi_pedprod ep where ep.db_edii_nro = pe.db_ped_ord_compra and pp.db_pedi_pedido = pe.db_ped_nro and rownum = 1) as “Ped_Edi”,
      ep.db_edii_produto,
      pp.db_pedi_produto,
      pd.db_prod_descricao,
      ep.db_edii_qtde_vda,
      ep.db_edii_preco_bru,
      ep.db_edii_preco_liq,
      ep.db_edii_perc_dcto,
      (select distinct edp.db_edip_lote from db_edi_pedido edp where edp.db_edip_nro = pe.db_ped_ord_compra) as Lote,
      (select pe.db_ped_nro from db_pedido pe where pe.db_ped_nro = pp.db_pedi_pedido and pe.db_ped_cliente = cedi.db_clied_codigo and rownum = 1) as “Pedido_Nro”,
      ep.db_edii_preco_merc,
      pp.db_pedi_preco_liq,
      pp.db_pedi_qtde_solic,
      pp.db_pedi_qtde_atend,
      (pp.db_pedi_qtde_solic) – (pp.db_pedi_qtde_atend) as Qtde_Cancelada,
      (pp.db_pedi_qtde_solic) – (ep.db_edii_qtde_vda) as Qtde_Alterada,
      pe.db_ped_situacao,
      decode(pe.db_ped_situacao,0,’Liberado’,1,’Bloqueado’,2,’Faturado Parcial’,4,’Faturado’,9,’Cancelado’) as Pedido_Cancelado,
      (select nf.db_nota_nro from db_nota_fiscal nf where pp.db_pedi_atd_dcto = nf.db_nota_nro and rownum = 1) as nota
      from db_edi_pedprod ep, db_pedido_prod pp, db_produto pd, db_pedido pe, db_edi_pedido edp, db_nota_fiscal nf, db_cliente_edi cedi, db_cliente cl
      where ep.db_edii_produto = pd.db_prod_cod_barra
      and pd.db_prod_codigo = pp.db_pedi_produto
      –and ep.db_edii_comprador = ‘7895000000001’
      and cl.db_cli_vinculo = ‘20374’
      and pe.db_ped_nro = pp.db_pedi_pedido(+)
      and edp.db_edip_comprador = ep.db_edii_comprador(+)
      and ep.db_edii_nro = pe.db_ped_ord_compra
      and pe.db_ped_empresa = edp.db_edip_empresa
      –and cedi.db_clied_codigo = pe.db_ped_cliente
      and pe.db_ped_nro (+)= nf.db_nota_ped_merc
      –and nf.db_nota_ped_orig = pe.db_ped_nro_orig(+)
      and nf.db_nota_cliente = cedi.db_clied_codigo
      and cedi.db_clied_codigo = cl.db_cli_codigo
      and cl.db_cli_codigo = nf.db_nota_cliente
      and pe.db_ped_tipo = ‘EDI’
      –and pe.db_ped_dt_emissao = ’29/11/2016′
      and pe.db_ped_ord_compra = ‘9768860735091’

      Dessa forma ele retorna a informação precisamente, porém quando coloco pela opção da data que está comentada ai fica rodando por muito tempo, preciso de um help para melhorar o desempenho dessa query!

      #108558
      Avatar photoJosé Laurindo Chiappa
      Moderador

        Blz ? Então, necessariamente ninguém tem como analisar uma query longa e complexa pra vc (assim sendo, um dos trabalhos que VOCÊ terá que fazer é não analisar a query completa que nem veio da produção, mas ir ‘tirando’ componentes , diminuindo-a, pra tentar chegar no ponto pior pra performance : NINGUÉM pode fazer esse trabalho por você), mas sem muita análise vou dar algumas Sugestões :

        a) vc NUNCA, JAMAIS, de MANEIRA ALGUMA, deve ter conversão de datatype implícita (ie, comparara data ou número com strings, ou coisas assim) que AO QUE PARECE é o que vc está fazendo na linha abaixo, se a coluna db_ped_dt_emissao for do tipo DATE) :

        and pe.db_ped_dt_emissao = ’29/11/2016′

        há DIVERSAS razões para isso, mas as mais importantes é que isso pode levar a Invalidar o uso de eventuais índices na coluna (pois o índice indexou DATAS e vc está comaparando STRINGS, que Não São o que está dentro do Índice), E também ocorre que o Otimizador de SQL do RDBMS coletou estatísticas da DATA, no momento que vc passa uma string, de strings ele não conhece pra esse coluna…. O correto seria :

        and pe.db_ped_dt_emissao = TO_DATE(’29/11/2016′, ‘DD/MM/YYYY’)

        aí si, Não tem COMO ter conversão implícita….

        Me parece Inclusive que vc cai NOVAMENTE em conversão implícita na linha :

        and pe.db_ped_ord_compra = ‘9768860735091’

        se essa coluna db_ped_ord_compra for NUMBER, o que parece ser… O correto seria :

        and pe.db_ped_ord_compra = 9768860735091

        aí Sim, tá comparamdo NUMBER com número…

        b) não dá pra sabermos se o que eu vou dizer tá “pegando” aí pra vc ou não (só quando vc fizer a ANÁLISE DE EXECUÇÃO, que vou comentar mais abaixo, é que saberemos) mas uma Bandeira VERMELHA total , um Indicador de Ineficiência comum, é quando vc usa a mesma tabela em vários lugares diferentes do SQL : via de regra, isso indica que essa tabela vai ter registros lidos REPETIDAS VEZES – em muitos casos, usando técnicas de SQL que agrupam os registros da tabela cfrme vão sendo lidos uma vez só (funções Analíticas são o arroz com feijão pra isso) vc poupa uma pancada de I/Os…

        ==> Análise de performance : para vc poder VER o que está tendo de diferença entre o SQL ‘rápido’ e o SQL ‘lento’ , vc precisará :

        1. levantar para ** TODAS ** as tabelas envolvidas quais colunas são Indexadas, o total de linhas de cada tabela E a distribuição de dados (ie, para as colunas referenciadas no WHERE ter uma noção de quantas linhas mais ou menos retornam para cada valor possível da coluna)

        2. obter o PLANO DE EXECUÇÂO REAL (*** não é *** o Plano estimado pela EXPLAIN PLAN!!!) tanto para uma execução “rápida” quanto para a execução “lenta” : uma das opções pra isso é, numa janela separada, via sql*plus provavelmente, vc executar a query com as condições em que ela vai rápida e coletar as stats , e em outra janela vc executar a query com as condições em que ela fica lenta, mas em ambos os casos passando a HINT de GATHER_PLAN_STATISTICS – imediatamente depois da execução, vc puxa o plano com DBMS_XPLAN.DISPLAY_CURSOR… https://blogs.oracle.com/optimizer/entry/how_do_i_know_if dá um exemplo…

        3. compare os planos obtidos entre si, para ver ONDE tá demorando quais, que diferenças tão aparecendo (muito provavelmente vai ter algum índice que uma usa e outra não), COMPARE as estimativas de linhas previstas contra as qtdades de linhas realmente lidas (A-ROWS x E-ROWS), veja se as operações de JOINs sendo feitas tem alguma diferença de ordem ou método são COERENTES com os índices e distribuição de dados que vc coletou no passo 1….

        ** FEITA ESSA ANÁLISE **, vc deverá encontrar a CAUSA da sua diferença de performance, okdoc ??

        []s

        Chiappa

        OBS :

        => nem preciso dizer, muito CERTAMENTE vc vai ter que acionar seu DBA para que ele te dê permissão de execução nessa package DBMS_XPLAN

        => temos também a opção de fazer um TRACE+TKPROF nas sessões executando os SQLs (veja qui mesmo no Fórum que em respostas prévias dei exemplo de como fazer) : isso porém é mais apropriado para quando vc quer fazer análise de WAITs, e no seu caso parece ser mesmo Plano de Execução diferente sendo gerado…

      Visualizando 2 posts - 1 até 2 (de 2 do total)
      • Você deve fazer login para responder a este tópico.
      plugins premium WordPress