/ / executeブロックを使用してFirebirdの一括削除を最適化する方法 - データベース、クエリの最適化、firebird、delete-row

executeブロックを使用してFirebirdの一括削除を最適化する方法 - データベース、クエリの最適化、firebird、delete-row

私は60万行のFirebirdテーブルを持っていて、caを削除する必要があります。テーブルの半分

テーブルの行には、車のGPS位置、タイムスタンプがあります。記録および他のデータ。テーブルには、主キーIdVehicle + TimeStampと1つの外部キー(Vehicleテーブルへの)があります。他のキー、インデックス、またはトリガはありません。 1台の車両には100 000 - 500 000のレコードがあります。

古いデータを削除する必要があります。すべての車から2015年3月1日より古いデータを削除します。 "execute block" (主キーを使用) 最初に私は1.3.2015よりも古い1台の車両記録を読みました。それから私は個々のレコードを調べていき、SQLがブロックを実行してから50のエントリごとにfirebirdにそれを実行する準備をしています。

EXECUTE BLOCK AS BEGIN
DELETE FROM RIDE_POS WHERE IdVehicle = 1547 and date = "4.5.2015 8:56:47"
DELETE FROM RIDE_POS WHERE IdVehicle = 1547 and date = "4.5.2015 8:56:59"
DELETE FROM RIDE_POS WHERE IdVehicle = 1547 and date = "4.5.2015 8:57:17"
...... a total of 50 line
END

したがって、800秒あたり100万行を削除します(1ミリ秒間に約1レコード)。

レコードを簡単に削除する方法はありますか?

さらに、この方法で私はほんの数個しか削除できません100万行、それから私はfirebirdを再起動しなければなりません。初期の記録から素早くクリアされ、徐々にそしてより長い時間がかかります。

オリエンテーションでは、大規模なテーブルでレコードを定期的に消去する方法(テーブルを完全に消去するのではなく、レコードの一部だけを消去する方法)。

回答:

回答№1は2

削除したい場合 すべて 指定された日付よりも古いレコードは、車両に関係なく、その後、を含む意味はありません Idvehicle クエリでは、日付だけで十分です。すなわち次のようにする必要があります、まっすぐなクエリでは、必要はありません execute block どちらか:

DELETE FROM RIDE_POS WHERE date < "2015-03-01"

回答№2の場合は1

何千もの削除が必要な場合100万件のレコードが1回のトランザクションで実行されることはありません。たとえば、1000レコードを削除してコミットしてから、他の1000レコードを削除してコミットするなど、いくつかの手順でそれを実行するほうがよいでしょう。 1000は規則ではありません、それはあなたの特定の状況に依存します(あなたの記録がどれくらい大きいか、それらが「削除カスケード」で外部キーを介して持っているリンクデータの数)。また、 "削除時"のトリガーがあるかどうかを確認してください。一時的に無効にすることも可能です。


回答№3の場合は0

たぶん、組み合わせたアプローチが助けになるでしょう。

  1. 日付に(一時的に)インデックスを追加します。

    CREATE INDEX IDX_RIDE_POS_date_ASC ON RIDE_POS (date)

  2. 実行ブロックを書く:

    
    EXECUTE BLOCK
    AS
    DECLARE VARIABLE V_ID_VEHICLE INTEGER;
    BEGIN
    FOR SELECT
    DISTINCT ID_VEHICLE
    FROM
    RIDE_POS
    INTO
    :V_ID_VEHICLE
    DO BEGIN
    DELETE FROM RIDE_POS WHERE IdVehicle = :V_ID_VEHICLE AND date < "1.3.2015"
    END
    END
    

  3. もう必要ない場合は、インデックスを削除してください。

    DROP INDEX IDX_RIDE_POS_date_ASC"

インデックスを作成するのに必要な時間を考慮しても、レコードを削除する時間を節約できると思います。


回答№4の場合は0

最後に、私は問題がどこにあったか見つけました。 主な問題は、私が古典的なWinformsアプリケーション(またはIBExpert)を使用していることと、それが紙詰まりの原因となり、照会が遅くなることでした。ブロックを実行してデータ部分を消去することで、紙詰まりの問題を解決しましたが、時間がかかりました。

解決策は、単純なコンソールアプリケーションを作成し、そこからクエリを実行することでした。 主キーをそのままにして消去し(インデックスの追加や削除はしません)、レコードの削除速度はミリ秒あたり約65(16秒あたり100万行)でした。

プライマリを削除してdatetime列にインデックスを追加しようとしたとき、消去するよりもわずか約5〜10%スピードアップします。