[firebase-br] Ref. Execução de PLAN FIREBIRD

Omar Haddad omarhaddadm em gmail.com
Sex Jul 9 12:02:31 -03 2010


Bom dia, srs. e sras.

Tenho a seguinte querie abaixo:

--------------------

SELECT '10' as TipoRegistro,
    Coalesce(E.PROGRAMA,0) as codPrograma,
    o.CODIGO_ORGAO_TCMS as codOrgao,
    Coalesce(u.CODIGO_UNIDADE_TCMS,0) as CodUnidade,
    Coalesce(e.FUNCAO,0) as CodFuncao,
    Coalesce(e.SUB_FUNCAO,0) as CodSubFuncao,
    CASE WHEN e.PROJETO IS NOT NULL THEN substr(e.PROJETO,1,1) ELSE '0' END
as naturezaAcao,
    CASE WHEN e.PROJETO IS NOT NULL THEN substr(e.PROJETO,2,4) ELSE '000'
END as nroProjAtiv,
    CASE WHEN e.NATUREZA_DESPESA IS NOT NULL THEN
substr(e.NATUREZA_DESPESA,1,6) ELSE '000000' END as elementoDespesa,
    '00' subElemento,
    '000000000000000000000' as DotOrigP2001,
    Coalesce(e.NUMERO,0) as NroEmpenho,
    p.NUMERO as nroOp,
    ap.EMISSAO as DtAnulacaoOp,
    ap.NUMERO as nrAnulacaoOp,
    CASE
     WHEN P.TIPO_NOTA = 'E' THEN
       CASE WHEN E.EXERCICIO IS NOT NULL THEN
         '3' /* RESTOS A PAGAR */
       ELSE
         '9' /* EXTRA ORÇAMENTÁRIA */
       END
     ELSE
       CASE WHEN ((E.VALOR = PE.VALOR) AND
            (EXTRACT(MONTH FROM E.DATA_EMISSAO) = EXTRACT(MONTH FROM
P.DATA_BAIXA))) THEN
         '1' /* DESPESA TOTALMENTE PAGA NO MES */
       ELSE
         '2' /* DESPESA A PAGAR */
       END
    END AS TipoOp,
    Coalesce(E.DATA_EMISSAO, p.DATA_BAIXA) AS DtInscricao,
    p.DATA_BAIXA as DtEmissao,
    Coalesce(pe.VALOR, p.VALOR_BRUTO) as ValorOp,
    (Coalesce(pe.VALOR, p.VALOR_BRUTO) * p.VALOR_BRUTO) /
ap.VALOR_BRUTO_NOTA as ValorAnuladoOp,
    c.CGC_CPF as CpfCnpf,
    C.NOME AS nOMEcREDOR,
    P.DESCRICAO AS especificacaoOp
FROM ANULACAOPAGAMENTO AP
JOIN PAGAMENTO P ON (P.GESTAO = AP.GESTAO AND P.EXERCICIO =
AP.EXERCICIO_NOTA AND P.NUMERO = AP.NUMERO_NOTA)
JOIN CREDOR C ON (C.CGC_CPF = P.CREDOR)
LEFT JOIN PAGAMENTOEMPENHO PE ON (PE.GESTAO = P.GESTAO)
               AND (PE.EXERCICIO = P.EXERCICIO)
               AND (PE.NUMERO = P.NUMERO)
LEFT JOIN EMPENHO E ON (E.GESTAO = PE.GESTAO)
          AND (E.EXERCICIO = PE.EXERCICIO_EMPENHO)
          AND (E.NUMERO = PE.NUMERO_EMPENHO)
join orgao_gestor o on (o.GESTAO = P.GESTAO)
LEFT JOIN UNIDADE u on (u.GESTAO_CONTROLE = e.GESTAO_CONTROLE)
        and (u.EXERCICIO = e.EXERCICIO)
        and (u.CODIGO = e.UNIDADE_ORCAMENTARIA)

LEFT JOIN RECURSO r on (r.GESTAO_CONTROLE = e.GESTAO_CONTROLE)
        and (r.EXERCICIO = e.EXERCICIO)
        and (r.FONTE_RECURSO = e.FONTE_RECURSO)
WHERE AP.GESTAO = :GESTAO
AND  AP.EXERCICIO = :EXERCICIO
AND  AP.MES = :MES
AND  P.DATA_BAIXA IS NOT NULL
and  ((:Legislativo = 'S') AND ((e.UNIDADE_ORCAMENTARIA = 101) OR
(e.UNIDADE_ORCAMENTARIA is null))
or  ((:Legislativo = 'N') AND ((e.UNIDADE_ORCAMENTARIA <> 101) OR
(e.UNIDADE_ORCAMENTARIA is null))))

Ela está lenta demorando cerca de 15 segundos. Tem uma outra query similar a
esta que demora 32s para me trazer os resultados (no máximo 5 regs.)

Agora, vem a questão:


[01]. Para cada join devo ter um índice com os mesmos campos ou não ? E se a
tabela for usada em mais de um JOIN e por outros campos diferentes, como o
Firebird trata ?

[02.] Quando a tabela tem uma PK, exemplo da tabela CREDOR (no select)

   JOIN CREDOR C ON (C.CGC_CPF = P.CREDOR)

eu preciso ter um índice também pelo CGC_CPF ? Ele não considera
automaticamente no seu PLAN de execução o índice mais apropriado ou não ?


Obrigado

Abraço a todos.

-- 
Att.
Omar Marques Haddad
Analista de Sistemas Sênior



Mais detalhes sobre a lista de discussão lista