Share Button

Uma tabela com um único índice já monta uma estatística que indica qual a distribuição
espacial dos dados organizados pelo índice. Se a tabela possui vários índices o firebird utiliza
as estatísticas para escolher os melhores índices para responder a solicitação do usuário.
Sempre que é feito INSERT, UPDATE em uma coluna que pertence a um índice, o índice é
atualizado, mas sua estatítica não segue a mesma mecânica (ocorre uma espécie de
fragmentação do índice).
Se o firebird decide com base na estatítica do índice, não é difícil imaginar que com a
fragmentação o que deveria ser um benefício passa a ser um problema.
Então o firebird recomenda que depois de algum tempo – as estatísticas do banco de dados
sejam refeitas para refletir com melhor precisão a situação do índice.
Para facilitar este trabalho, segue uma procedure que força a atualização dos índice de todas
as suas tabelas.

SET TERM ^ ;
CREATE OR ALTER PROCEDURE REINDEX
as
declare variable sql varchar(255);
begin
   for
     select rdb$index_name from rdb$indices
     into :sql
   do
   begin
      sql = 'SET STATISTICS INDEX ' || sql;
      execute statement :sql;
   end
end^
SET TERM ; ^
GRANT EXECUTE ON PROCEDURE REINDEX TO SYSDBA;

Share Button

Restaurou o banco de dados com os índices inativados? Claro que era somente um situação de contingência,
porque você continua precisando deles. Então para REATIVAR os índices novamente, rode este código no
banco de dados:
As tabelas que apresentarem erros, o índice não será ativado, mas você continua precisando dele –
recomendo avaliar e corrigir – depois de corrigir, rode o script novamente.

SET TERM ^;
execute block returns (x varchar(255))
as
declare variable ordem integer;
declare variable stm varchar(1024);
begin
   for
     select y,stm, x from (
        SELECT 1 y,' alter index '||trim(rdb$index_name)||' active ' stm , rdb$index_name x from rdb$indices
    where rdb$index_inactive=1
          and (not rdb$index_name like 'FK%')
          and rdb$unique_flag=0
  union
     SELECT 2 y, ' alter index '||trim(rdb$index_name)||' active ' stm , rdb$index_name x from rdb$indices
     where rdb$index_inactive=1
           and (not rdb$index_name like 'FK%')
           and rdb$unique_flag=1
  union
     SELECT 3 y, ' alter index '||trim(rdb$index_name)||' active ' stm , rdb$index_name x from rdb$indices
     where rdb$index_inactive=1
           and (rdb$index_name like 'FK%')
    ) k order by y
into :ordem, :stm, :x
do
begin
    in autonomous transaction do
       execute statement stm;
    --execute statement 'commit work';
    suspend;
    when any do
      begin
        --exception;
      end
    end
end^
SET TERM;^