[firebase-br] Indice

Adriano Luiz de Souza adriano em riodeserto.com.br
Ter Mar 10 13:08:09 -03 2009


Bom Dia a Todos ! Eu tenho uma tabela em um banco firebird 2.1 de 
aproximadamente 2.2GB. Eu armazeno os lançamentos contabeis em uma 
tabela chamada tb_contabilizacao. Essa tabela possui 400.000 registros, 
com suas respectivas chaves estrangeiras criadas. No entanto, percebi 
que algumas querys para retornar os lançamentos contábeis do registro 
referente  levam cerca de 2 segundos para retornar, isso em apenas 
alguns casos... A tabela possui atualmente 19 FK e algumas a query 
retornam instantaneamente, outras demoram esse tempo de 2 segundos. 
Analisando o plano, eu percebi que ele utiliza o índice para priorizar o 
Join com a tabela tb_conta_contabil. Na minha opinião, ele deveria 
utilizar um outro índice, por sinal o índice da foreign key, pois este 
índice iria posicionar direto nos registros de interesse, ao invés da 
tabela toda. Segue o exemplo para ficar mais claro:


select c.cd_contabilizacao,
c.cd_empresa, c.dt_contabil, c.nr_documento,
c.fg_db_cr, c.vl_contabil, c.ds_observacao, c.cd_conta_contabil,
c.cd_movimento_bancario, cc.ds_conta_contabil, cc.cd_contabil, c.cd_pessoa
from TB_CONTABILIZACAO c
inner join  tb_conta_contabil cc on ( c.cd_conta_contabil = 
cc.cd_conta_contabil )
where c.cd_nota_entrada = 284431

Plan
PLAN JOIN (C INDEX (FK_TB_CONTABILIZACAO_2), CC INDEX (PK_CONTA_CONTABIL))

Adapted Plan
PLAN JOIN (C INDEX (FK_TB_CONTABILIZACAO_2), CC INDEX (PK_CONTA_CONTABIL))

*Esta query usa o plan corretamente, pois utiliza o indice 
FK_TB_CONTABILIZACAO_2, que é o índice da FK de TB_NOTA_ENTRADA
*
No entanto, esta mesma query utilizando outra chave, acaba por não 
utilizar um plano similar

select c.cd_contabilizacao,
c.cd_empresa, c.dt_contabil, c.nr_documento,
c.fg_db_cr, c.vl_contabil, c.ds_observacao, c.cd_conta_contabil,
c.cd_movimento_bancario, cc.ds_conta_contabil, cc.cd_contabil, c.cd_pessoa
from TB_CONTABILIZACAO c
inner join  tb_conta_contabil cc on ( c.cd_conta_contabil = 
cc.cd_conta_contabil )
where c.cd_movimento_bancario = 400000

Plan
PLAN JOIN (CC NATURAL, C INDEX (FK_TB_CONTABILIZACAO_1))

Adapted Plan
PLAN JOIN (CC NATURAL, C INDEX (FK_TB_CONTABILIZACAO_1))

Neste caso, ele está usando o índice da foreign key de 
tb_conta_contabil, fazendo assim um table scan para retornar os 
registros desejados.


Como sou usuário de Sybase, vou perguntar conforme o que acontece no 
Sybase: Existe alguma maneira de fazer o banco utilizar o índice correto 
? No sybase existe um comando chamado update statistcs para que atualize 
as estatísticas do índice e o banco passe a utiliza-lo. Existe isso no 
firebird ? Ou serei obrigado a usar a query dessa forma:

select c.cd_contabilizacao,
c.cd_empresa, c.dt_contabil, c.nr_documento,
c.fg_db_cr, c.vl_contabil, c.ds_observacao, c.cd_conta_contabil,
c.cd_movimento_bancario, cc.ds_conta_contabil, cc.cd_contabil, c.cd_pessoa
from TB_CONTABILIZACAO c
inner join  tb_conta_contabil cc on ( c.cd_conta_contabil = 
cc.cd_conta_contabil )
where c.cd_movimento_bancario = 400000
plan ( c index ( fk_tb_contabilizacao_18 ), cc natural  )

Em Anexo, segue a DDL da tabela tb_contabilizacao


Adriano







Mais detalhes sobre a lista de discussão lista