PostgreSQLでこの種のタスクを実行するための最速の方法は何でしょうか。可能な限り最速のソリューションに興味があります。
私は自分自身がMySQLのためのそのような種類のソリューションであることに気づきました。それは、テーブルを1つずつ切り捨てるよりもはるかに高速に実行されます。しかしとにかく、私はMySQLの最速のソリューションにも興味があります。ここで私の結果を参照してください。もちろん、MySQLの場合のみです:https ://github.com/bmabey/database_cleaner/issues/126
私は次の仮定を持っています:
- 私は30〜100のテーブルを持っています。30にします。
- テーブルの半分は空です。
- 空でない各テーブルには、たとえば100行以下があります。つまり、テーブルは大きくありません。
この手順から2つまたは5つまたはN個のテーブルを除外するオプションの可能性が必要です。
私はできません!トランザクションを使用します。
PostgreSQLで8と9の両方で動作するこのような場合には、最速のクリーニング戦略が必要です。
私は次のアプローチを見ます:
各テーブルを切り捨てます。特に空のテーブルの場合は遅すぎると思います。
より高速な方法で各テーブルの空をチェックし、空の場合は、一意の識別子列(MySQLのAUTO_INCREMENTのアナログ)を初期状態(1)にリセットします。つまり、last_valueをシーケンスから1に戻します。それ以外の場合は、truncateを実行します。その上に。
私はRubyコードを使用してすべてのテーブルを反復処理し、各テーブルで以下のコードを呼び出し、次のように各テーブルに対して実行されるSQLコードをセットアップしようとしました。
DO $$DECLARE r record;
BEGIN
somehow_captured = SELECT last_value from #{table}_id_seq
IF (somehow_captured == 1) THEN
== restore initial unique identifier column value here ==
END
IF (somehow_captured > 1) THEN
TRUNCATE TABLE #{table};
END IF;
END$$;
このコードをさまざまな面で操作しましたが、PostgreSQLの関数とブロック(および変数)に慣れていないため、機能させることができませんでした。
また、EXISTS(SELECT something FROM TABLE)は、「チェック手順」ユニットの1つとしてうまく機能するために使用できると思いました。クリーニング手順は構成されているはずですが、まだ達成されていません。
この手順をPostgreSQLネイティブの方法で実行する方法についてのヒントをいただければ幸いです。
アップデート:
RubyまたはRubyonRailsプロジェクトのユニットテストと統合テストを実行するには、これらすべてが必要です。各テストには、実行前にクリーンなDBが必要です。または、テスト自体の後にクリーンアップ(いわゆるティアダウン)を実行する必要があります。トランザクションは非常に優れていますが、特定のWebドライバーに対してテストを実行すると使用できなくなります。私の場合、切り捨て戦略への切り替えが必要です。RoRを参照して更新した後は、「明らかに、PG用のDatabaseCleanerが必要です」などの回答をここに投稿しないでください。
更新2:
ここで説明する戦略は、最近、DatabaseCleaner、https://github.com/bmabey/database_cleanerに:pre_countオプションとしてマージされました(READMEを参照)。