我们在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有关,但我们无法确定原因。为确保数据页面一致性,在每个检查点之后对数据页面进行的第一次修改会导致记录整个页面内容。
有什么建议吗?
postgresql.conf
可能是指的吧?我从来没有听说过 "postgre.conf" :-P - Craig Ringer