2009-05-19 14 views
13

私が埋め込まれており、Firebirdのサーバーの両方のFirebirdを使用して、時々私は、次のような手順を使用して、テーブルのインデックスを再作成する必要があります。Firebirdは手動で再索引付けする必要がありますか?

CREATE PROCEDURE MAINTENANCE_SELECTIVITY 
ASDECLARE VARIABLE S VARCHAR(200); 
BEGIN 
FOR select RDB$INDEX_NAME FROM RDB$INDICES INTO :S DO 
BEGIN 
S = 'SET statistics INDEX ' || s || ';'; 
EXECUTE STATEMENT :s; 
END 
SUSPEND; 
END 

私はこれが埋め込まれて使用して、通常のだと思いますが、それは本当に使用して必要とされていますサーバー?必要なときや定期的にサーバーを自動的に実行するようにサーバーを構成する方法はありますか?

+2

ちょっとメモ。 SUSPENDはこの手順では不要です。 –

+0

ありがとう!私はそれをどこかからコピーしたと思う。 – pablo

+2

実際に、索引統計は再索引付けされず、再計算されません。大きな表では、再索引付けが非常に遅くなることがあります。統計の計算は常に迅速です。 –

答えて

20

まず、私はFirebirdの専門家ではないことを指摘しておきます。だから、SQL Serverの仕組みに基づいて答えています。

この場合、答えは「はい」と「いいえ」の両方です。

新しい行を挿入すると、そのテーブルのすべてのインデックスにその行が格納されるため、インデックスがSQL Server上で更新されます。基本的に、そのパーツが動作するためにテーブルを再インデックス化し続ける必要はありません。それは「いいえ」の部分です。

ただし、問題はインデックスではなく、統計情報で示されます。あなたはテーブルのインデックスを再作成する必要があると言っていますが、統計を操作するコードを表示しているので、その理由がわかります。

簡単な答えは、時間が経つにつれて統計がゆっくりと外に出るということです。それらは使用できなくなるまで悪化することはありませんが、再作成/再計算する際の完全なレベルから低下します。それは「はい」の部分です。

古い統計の主な問題は、インデックス内のキーの分布が大幅に変更された場合、統計が直ちにそのインデックスを取得しない可能性があるため、クエリオプティマイザは古いインデックス、古くなった統計データを手元に持っています。

例えば、インデックスの1つが、キーが値のスペースの両端に集約されているという統計があるとします(たとえば、0と1のロットが多いint-column)。次に、たくさんの行を挿入して、このインデックスに値全体がスペクトル全体に広がるようにする値を挿入します。

このインデックスを持つテーブルに対して選択性の低い(0と1が多い)列で、別のテーブルの結合を使用するクエリを実行すると、クエリオプティマイザはこのインデックスがこれは、同時に使用される(同じデータページ上にある)多くの行をフェッチするためです。

しかし、データが変更されているため、関連する部分を見つけるためにインデックス全体にジャンプします。結局のところそれほど良くありません。

統計を再計算した後、クエリオプティマイザは、このインデックスがこのクエリに対して最適ではないことを確認し、代わりに別のインデックスを選択することができます。

基本的に、データが流動的である場合は、定期的に統計を再計算する必要があります。データがほとんど変更されない場合は、頻繁に行う必要はありませんが、これを行う定期的なメンテナンスジョブを追加します。

Firebirdに単独でそれを依頼することができるかどうかについては、やはり私は薄い氷の上にいるのですが、私はそこにいると疑います。 SQL Serverでは、これをスケジュールで実行するメンテナンスジョブを設定することができます。少なくとも、Windowsスケジューラからバッチファイルを取り出して、そのような処理を行うことができるはずです。

+3

+1完全な説明 – idursun

+0

正確には、膨大な数のデータが導入されたときに実際に統計を再計算することが重要になることがあり、Firebirdが自動的に再計算しないことが懸念されています。 SQL Serverのような仕事でそれを行う方法。 – pablo

+1

次に、適切なコマンドラインツールを呼び出し、あなたが必要とするSQLステートメントまたはsprocsを実行するバッチファイルが、あなたが唯一の選択肢だと思います。あなた自身がツールを作ることができます。 –

7

索引の重み付けを再作成しません。索引の重みを再計算します。索引は、最適化索引を最適化するために使用されます。インデックスサイズが大きく変わらない限り、これを行う必要はありません。データを追加する前に索引を作成する場合は、再計算を行う必要があります。

EmbeddedとServerは、プロセスモデルとまったく同じ機能を持つ必要があります。

+0

です。しかし、とにかく、それはパフォーマンスに大きな影響を与えます。 だから、自動的にそれを行う人はいませんか? – pablo

+0

データは変更されても索引は更新されますが、重みは更新されません。したがって、データが大きく変更された場合は、手動で再計算する必要があります。 – Harriv

2

新しいファイアバードについてこの回答を更新したいと考えていました。ここに更新されたdsqlがあります。

SET TERM^; 
CREATE OR ALTER PROCEDURE NEW_PROCEDURE 
AS 
DECLARE VARIABLE S VARCHAR(300); 
begin 
    FOR select 'SET statistics INDEX ' || RDB$INDEX_NAME || ';' 
    FROM RDB$INDICES 
    WHERE RDB$INDEX_NAME <> 'PRIMARY' INTO :S 
    DO BEGIN 
    EXECUTE STATEMENT :s; 
    END 
end^ 
SET TERM ;^

GRANT EXECUTE ON PROCEDURE NEW_PROCEDURE TO SYSDBA; 
関連する問題