web-dev-qa-db-ja.com

テーブル全体をスキャンせずに、追加専用のPostgreSQL DBですべての新しいトランザクションの可視性を維持する方法

状況

PostgreSQL v11

私は12のテーブルを持つデータベースを持っています。 DELETEdまたはUPDATEdである行はありません。データの大部分は、毎日 '少数'(最大1,000)のトランザクションですべてのテーブルにINSERTedされます。一部のテーブルは、INSERTの実行中に数十GBのデータを追加できます(現在、最大のものは約20億行を持っています)。

問題

ある時点で、DBからデータを読み取るために使用するSELECTクエリがindex only scansの使用を停止することに気付きました。掘り下げた後、これはvisibility mapが古くなっていることが原因であることが明らかになりました。これは、index only scansの使用に戻るときにVACUUMを実行して確認されます。ただし、VACUUMは非常に高価で(最大のテーブルで10時間以上かかる可能性があります)、AUTOVACUUMまたはDELETE操作がないため、UPDATEはトリガーされません。

私は各トランザクションの後にVACUUM FREEZEを実行することを検討しましたが、各トランザクションの後にテーブル全体をスキャンする必要があるようですが、これにも時間がかかります。

質問

毎回テーブル全体をスキャンせずに、すべての新しいトランザクションを追加専用のPostgreSQLで可視としてマークする最良の方法は何ですか?

1
afonja

VACUUM (FREEZE)をときどき実行する必要があります。実行しない時間が長いほど、実行する必要があり、時間がかかります。

VACUUMを高速化するには、maintenance_work_mem

0
Laurenz Albe

毎回テーブル全体をスキャンせずに、すべての新しいトランザクションを追加専用のPostgreSQLで可視としてマークする最良の方法は何ですか?

PostgreSQLは、すべての表示済み/すべて凍結済みとしてすでにマークされているテーブルの部分をスキャンする必要はありません。廃止されたタプルがまったくない場合(追加のみのワークロードの場合、INSERTの一部がロールバックされない限り、何もないはずです)、インデックスをスキャンする必要がない場合もあります。だからあなたが心配している問題は実際には存在しないと思います。

ただし、私の場合、VACUUMは非常に高価です(最大のテーブルでは10時間以上かかることがあります)。

そのバキュームを実行する前に、どれくらいの間それを手放しましたか?その次の次はどれくらいかかりましたか? VACUUMが完了するまでに10時間かかることによる本質的な問題はありません。それが問題である場合は、それに関する問題を説明する必要があります。

0
jjanes