[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