Melhorar a performance desse Select

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
  

Mensagemem Ter, 21 Set 2010 8:44 am

Bom dia, como poderia melhorar a performance desse select?

Código: Selecionar todos
SELECT FIL.CODFIL LOJA,
       FIL.CIDADE,
       TO_CHAR(NRO.DATANRSORTE, 'DD/MM/YYYY') DATAVENDA,
       COUNT(NRO.NROSORTE) CARTELAS
  FROM CYBELAR_NROSORTE NRO, CAD_FILIAL FIL
WHERE NRO.FLGUSO = 1
   AND NRO.NOMCLI IS NOT NULL
   AND NRO.LOJA = FIL.CODFIL
   AND TO_CHAR(NRO.DATANRSORTE, 'MMYYYY') = <mes_ano>
   AND NRO.LOJA = <numero da loja>
GROUP BY FIL.CODFIL, FIL.CIDADE, TO_CHAR(NRO.DATANRSORTE, 'DD/MM/YYYY')
ORDER BY LOJA, DATAVENDA
facc
Localização: Cerquilho / SP

Mensagemem Ter, 21 Set 2010 9:00 am

desses campos quais são indices ?

NRO.FLGUSO
NRO.NOMCLI
NRO.LOJA
FIL.CODFIL
NRO.DATANRSORTE
NRO.LOJA
DATAVENDA


eu tenho comigo o mito de que o join deve ser o primeiro item do where..
mas não sei se isso realmente otimiza
Código: Selecionar todos
...
WHERE NRO.LOJA = FIL.CODFIL
   AND NRO.NOMCLI IS NOT NULL
   AND NRO.FLGUSO = 1
   AND TO_CHAR(NRO.DATANRSORTE, 'MMYYYY') = <mes_ano>
   AND NRO.LOJA = <numero da loja>
GROUP BY FIL.CODFIL, FIL.CIDADE, TO_CHAR(NRO.DATANRSORTE, 'DD/MM/YYYY')
ORDER BY LOJA, DATAVENDA
victorhugomuniz
Localização: Rio de Janeiro - RJ

Jesus está voltando, volte antes para Ele.

Imagem JavaBlackBelt

Mensagemem Ter, 21 Set 2010 9:09 am

Poste o explain plan aí... Qual a versão do teu Oracle?
burga
Localização: SP

Mensagemem Ter, 21 Set 2010 9:25 am

não se se foi isso que solicitou

Imagem
facc
Localização: Cerquilho / SP

Mensagemem Ter, 21 Set 2010 9:26 am

Isso aqui está péssimo:
Código: Selecionar todos
AND TO_CHAR(NRO.DATANRSORTE, 'MMYYYY') = <mes_ano>]


Poderia ser assim:
Código: Selecionar todos
AND NRO.DATANRSORTE >= trunc( p_data, 'MM')
AND NRO.DATANRSORTE <  trunc( add_months(p_data,1), 'MM')


Dessa forma não precisa usar função no campo.
dr_gori
Localização: Seattle, WA, USA

Thomas F. G

Mensagemem Ter, 21 Set 2010 9:31 am

victorhugomuniz escreveu:eu tenho comigo o mito de que o join deve ser o primeiro item do where..
mas não sei se isso realmente otimiza


Isso só é valido quando o otimizador está configurado para REGRA (RBO - rule based optimizer). Mas isso "saiu de linha" depois do oracle 9i, e o Cost Based Optimizer passou a ser padrão. (CBO). Daí a única coisa que importa é que tenha estatísticas atualizadas, histogramas, etc.
dr_gori
Localização: Seattle, WA, USA

Thomas F. G

Mensagemem Ter, 21 Set 2010 9:35 am

dr_gori escreveu:
victorhugomuniz escreveu:eu tenho comigo o mito de que o join deve ser o primeiro item do where..
mas não sei se isso realmente otimiza


Isso só é valido quando o otimizador está configurado para REGRA (RBO - rule based optimizer). Mas isso "saiu de linha" depois do oracle 9i, e o Cost Based Optimizer passou a ser padrão. (CBO). Daí a única coisa que importa é que tenha estatísticas atualizadas, histogramas, etc.


valeu pela explicação big boss.. :mrgreen:
victorhugomuniz
Localização: Rio de Janeiro - RJ

Jesus está voltando, volte antes para Ele.

Imagem JavaBlackBelt

Mensagemem Ter, 21 Set 2010 9:37 am

Eu alterei a linha, mas está dando um erro

Código: Selecionar todos
AND NRO.DATANRSORTE >= trunc('01/09/2010', 'MM')
   and NRO.DATANRSORTE < trunc(Add_months('01/09/2010', 1), 'MM')


Dá o erro ORA-00932: inconsistent datatypes: expected DATE got NUMBER no sinal >=
facc
Localização: Cerquilho / SP

Mensagemem Ter, 21 Set 2010 9:41 am

tira
Código: Selecionar todos
trunc('01/09/2010', 'MM')



coloca
Código: Selecionar todos
to_char(to_date('01/09/2010'), 'MM')
victorhugomuniz
Localização: Rio de Janeiro - RJ

Jesus está voltando, volte antes para Ele.

Imagem JavaBlackBelt

Mensagemem Ter, 21 Set 2010 10:04 am

Muito obrigado a todos

Melhorou significavelmente a performance do select alterando de
Código: Selecionar todos
AND TO_CHAR(NRO.DATANRSORTE, 'MMYYYY') = <mes_ano>]

para
Código: Selecionar todos
AND NRO.DATANRSORTE >= trunc(to_date('01/09/2010'), 'MM')
   and NRO.DATANRSORTE < trunc(Add_months('01/09/2010', 1), 'MM')


antes era executado na casa dos minutos, agora passou a ser segundos!
facc
Localização: Cerquilho / SP

Mensagemem Ter, 21 Set 2010 12:36 pm

SHOW!

No caso que eu postei, eu estava considerando "p_data" como um tipo DATA. Por isso que deu erro quando você substituiu pra '01/09/2010' --> que é um string!

:-o :-o :-o
dr_gori
Localização: Seattle, WA, USA

Thomas F. G


  • Veja também
    Respostas
    ExibiÇões
    Última mensagem


      Voltar para PL/SQL

      Quem está online

      Usuários navegando neste fórum: Nenhum usuário registrado e 4 visitantes