RedHat で Postgres 9.2 を使用しています。次のような表があります。
CREATE TABLE BULK_WI (
BULK_ID INTEGER NOT NULL,
USER_ID VARCHAR(20) NOT NULL,
CHUNK_ID INTEGER,
STATE VARCHAR(16),
CONSTRAINT BASE_BULK_WI_PK PRIMARY KEY(BULK_ID,USER_ID)
);
CREATE INDEX BASE_BULK_WI_IDX01 ON BULK_WI(STATE, CHUNK_ID);
バッチ ジョブの一部として、最初に新しい BULK_ID を使用してテーブルに多数の行を追加します。新しいレコードはすべて CHUNK_ID = NULL、STATE = 'PENDING' です。挿入は 500K ~ 1.5M 行です。これが発生したときのテーブルのサイズは、15M レコードを超えます。
挿入後、チャンクでテーブルの処理を開始します。これを行うには、最初に次のチャンクのアイテムをいくつか選択してから、それらを処理します。アイテムの選択は、次のクエリで行われます。
UPDATE BASE_BULK_WI wi SET wi.STATE = 'PROCESSING', wi.CHUNK_ID = $1
WHERE wi.STATE='PENDING' AND wi.BULK_ID = $2
AND wi.USER_ID IN
(SELECT USER_ID FROM BASE_BULK_WI WHERE BULK_ID = $3
AND CHUNK_ID IS NULL AND STATE='PENDING' LIMIT $4 FOR UPDATE)
$1はチャンクの反復ごとに増加し、$2と$3は常に同じ (挿入された BULK_ID)、$4は通常 2,000 から 10,000 の間です。
問題は、最初の数チャンクの更新に時間がかかることです。たとえば、制限が 2000 の場合、ほとんどの更新は 1 秒未満で発生しますが、最初の数回は 2 分以上かかります。
これがなぜ起こるのか、そしてそれを修正する方法を理解しようとしています。ドキュメントを読んだ後:
データ ページの一貫性を確保するために、各チェックポイントの後にデータ ページを最初に変更すると、ページ コンテンツ全体がログに記録されます。
チェックポイントと WAL に関連していると思われますが、突き止めることはできませんでした。
助言がありますか?