私の質問には2つの部分があります。
最近、MSSQLからPostgresに移行しました。データベースを作成するときにMSSQLの世界で行ったことの1つは、データベースとトランザクションログの初期サイズを指定することでした。これにより、特にデータベースの「通常の」サイズが事前にわかっている場合は、断片化が減少し、パフォーマンスが向上しました。
サイズが大きくなると、データベースのパフォーマンスが低下します。たとえば、私が実行するワークロードには通常10分かかります。データベースが大きくなると、この時間が長くなります。 VACUUM、VACUUM FULL、VACUUM FULL ANALYZEを実行しても問題は解決しないようです。パフォーマンスの問題を解決するには、データベースを停止し、ドライブをデフラグしてから、VACUUM FULL ANALYZEを実行すると、テストのパフォーマンスが元の10分に戻ります。これは、断片化が私に痛みを引き起こしているものだと疑うようになります。
Postgresでテーブルスペース/データベーススペースを予約するための参照を見つけることができませんでした。間違った用語を使用して何も見つからないか、Postgresでファイルシステムの断片化を緩和する別の方法があります。
ポインタはありますか?
ソリューション
提供された回答は、私が疑い始めたことを確認するのに役立ちました。 PostgreSQLは複数のファイルにまたがってデータベースを格納します。これにより、断片化を心配せずにデータベースを拡張できます。デフォルトの動作では、これらのファイルをテーブルデータでいっぱいにパックします。これは、ほとんど変更されないテーブルには適していますが、頻繁に更新されるテーブルには適していません。
PostgreSQLは [〜#〜] mvcc [〜#〜] を使用して、テーブルデータへの同時アクセスを提供します。このスキームでは、更新のたびに、更新された行の新しいversionが作成されます(これは、タイムスタンプやバージョン番号など、だれが知っていますか?)。古いデータはすぐには削除されませんが、削除対象としてマークされます。実際の削除は、VACUUM操作が実行されるときに行われます。
これは曲線因子とどのように関連していますか?テーブルのデフォルトのフィルファクター100はテーブルページを完全にパックします。これは、テーブルページ内に更新された行を保持するスペースがないことを意味します。つまり、更新された行は元の行とは異なるテーブルページに配置されます。私の経験が示すように、これはパフォーマンスに悪影響を及ぼします。サマリーテーブルは非常に頻繁に更新されるため(最大1500行/秒)、フィルファクターを20に設定することを選択しました。つまり、テーブルの20%が挿入された行データ用で、80%が更新データ用です。これは過度に見えるかもしれませんが、更新された行のために予約された大量のスペースは、更新された行が元のページと同じページ内にとどまり、autovacuumデーモンが実行されて古い行を削除するまでにテーブルページがいっぱいにならないことを意味します。
データベースを「修正」するために、私は次のことを行いました。
ALTER TABLE "my_summary_table" SET (fillfactor = 20);
テストを再実行すると、データベースが何百万行ある必要があるほど大きい場合でも、パフォーマンスの低下は見られません。
TL; DR-ファイルの断片化は原因ではなく、表スペースの断片化でした。これは、特定のユースケースに合わせてテーブルのFILLFACTORを調整することで軽減されます。
これに近いのは--with-segsizeスイッチを使用してサーバーをコンパイルするときだけではありません。これは、テーブルがギグよりも多くのスペースを占有し、ファイルシステムがギグ上にある単一のファイルを処理できる場合に役立ちます。 20ギグを挿入する場合、このスイッチを使用しないと20ファイルを作成する必要があります。ファイルシステムがギグを介してファイルを処理できる場合は、ファイルを大きな値に設定するだけで、何らかの利点が得られ、最悪の場合は小さな利点が得られます。
CLUSTER http://www.postgresql.org/docs/9.1/static/sql-cluster.html およびFILLFACTOR http://www.postgresql.org/docsをご覧ください。 /9.1/static/sql-createtable.html 、 http://www.postgresql.org/docs/9.1/static/sql-createindex.html
FILLFACTORはテーブルとインデックスの両方に適用できることに注意してください。
まだ方程式を入力していない別の問題があります:HOT update。関連する回答:
FILLFACTOR
を20
doesと同じくらい低く設定すると、過度に見えます。テーブルのサイズが最大5倍に膨らみます。 HOT更新が機能する場合、それほど低くする必要はありません-通常。
例外があります:HOT更新は、以前のトランザクションからのデッドタプルのみを再利用でき、sameまたはconcurrentones。したがって、重い同時ロードや長いトランザクションが同じ行を繰り返し更新する場合は、このような低い(またはさらに低い)設定が必要になります。
大きな更新があり、テーブルの大部分を一度に変更する場合は、それらをいくつかのチャンクに分割し、理想的には、データページのローカルに収まるだけの数の行を一度に変更することをお勧めします。しかし、それを見積もり、調整することは困難です。
HOT更新が機能するのは、変更された列がインデックスに関与していない場合のみです(部分インデックスのデータとしても条件としても)。更新された列のインデックスでHOT更新をブロックしている可能性があります。それらが消耗品である場合、それらなしで全体的なパフォーマンスが向上する可能性があります。
最後に、 setautovacuum parameters per table を実行できます。 FILLFACTOR 20
だけではなく、より厳密な行のパッキングを可能にする積極的な設定で、頻繁に更新されるテーブルをターゲットにすることができます。
問題がファイルの断片化である場合は、問題はありません。 Postgresでは、各テーブルは独自のファイル、またはTOASTを使用している場合はファイルシステム内のファイルセットを取得します。これは、たとえば、テーブルをドロップするために事前にサイズ設定されたテーブルスペースファイルを作成するOracle(または明らかにMS-SQL)とは異なります-ただし、テーブルスペースファイルが拡張されたり、ファイルシステムが最初はひどく断片化しています。
あなたの2番目の質問について... MS-Windowsは私が断片化の問題を経験した唯一のOSであり、MS-Windowsを絶対的に実行しないので、ファイルシステムの断片化をきれいに処理する方法がわかりません最近必要です。おそらく、データベースファイルを独自のディスクに配置することで、ある程度軽減できます。