4

Firebird 2.5.1 Embedded を使用しています。私はほぼ200k行でテーブルを空にするために通常のことをしました:

delete from SZAFKI

出力は次のとおりです。16 秒かかりますが、これは許容できません。

Preparing query: delete from SZAFKI
Prepare time: 0.010s
PLAN (SZAFKI NATURAL)

Executing...
Done.
3973416 fetches, 1030917 marks, 116515 reads, 116434 writes.
0 inserts, 0 updates, 182658 deletes, 27 index, 182658 seq.
Delta memory: -19688 bytes.
SZAFKI: 182658 deletes. 
182658 rows affected directly.
Total execution time: 16.729s
Script execution finished.

Firebird には TRUNCATE キーワードがありません。クエリは PLAN NATURAL を使用するため、次のように手動でクエリを PLAN しようとしました。

delete from szafki PLAN (SZAFKI INDEX (SZAFKI_PK))

しかし、Firebird は「指定されたプランでは SZAFKI_PK を使用できません」と言います (主キーです) 質問は、テーブルを効率的に空にする方法です。ドロップして再作成することはできません。

4

3 に答える 3

7

私のコメントに基づいて答えます

あなたが試すことができるトリックは、を使用することです(が1以上であるとDELETE FROM SZAFKI WHERE ID > 0仮定します)。IDこれにより、Firebird は主キー インデックスを使用して行を検索するようになります。

私の最初の仮定は、これはインデックスなしの削除よりも悪いだろうということでした。インデックスなしの削除では、テーブルのすべてのデータページの順次スキャンが実行され、行が削除されます (つまり、削除されたスタブ レコードである新しいレコード バージョンが作成されます)。インデックスを使用すると、インデックス順に行が検索され、データページがランダム ウォークになります (挿入、削除、および更新による多数のレコード バージョンによるデータの断片化のレベルが高いと仮定します)。これは遅くなると予想していましたが、おそらく Firebird は、テーブルのすべてのデータページではなく、関連するデータページ (トランザクションに関連するレコード バージョンを含む) のみを読み取る必要があります。

于 2012-12-15T09:17:49.057 に答える
2

残念ながら、現在Firebirdのバージョンでは、(大きな)テーブル全体を大規模に削除する高速な方法はありません。「削除されたコンテンツ」がガベージコレクションされると、さらに長い遅延が予想されます(削除がコミットされた後、テーブルでselect *を実行すると表示されます)。削除を実行する前に、そのテーブルのインデックスを非アクティブ化して、それが役立つかどうかを確認できます。テーブルをある種の一時ストレージとして使用している場合は、GTT機能を使用することをお勧めします。

于 2012-12-13T16:25:22.390 に答える