[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