在PostgreSQL中相对较小的表上更新非常慢

时间:2011-05-26 11:06:25

标签: performance postgresql indexing

我有下表(来自pgAdmin的信息):

    CREATE TABLE comments_lemms
(
  comment_id integer,
  freq integer,
  lemm_id integer,
  bm25 real
)
WITH (
  OIDS=FALSE
);
ALTER TABLE comments_lemms OWNER TO postgres;

-- Index: comments_lemms_comment_id_idx

-- DROP INDEX comments_lemms_comment_id_idx;

CREATE INDEX comments_lemms_comment_id_idx
  ON comments_lemms
  USING btree
  (comment_id);

-- Index: comments_lemms_lemm_id_idx

-- DROP INDEX comments_lemms_lemm_id_idx;

CREATE INDEX comments_lemms_lemm_id_idx
  ON comments_lemms
  USING btree
  (lemm_id);

还有一张表:

CREATE TABLE comments
(
  id serial NOT NULL,
  nid integer,
  userid integer,
  timest timestamp without time zone,
  lemm_length integer,
  CONSTRAINT comments_pkey PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE comments OWNER TO postgres;

-- Index: comments_id_idx

-- DROP INDEX comments_id_idx;

CREATE INDEX comments_id_idx
  ON comments
  USING btree
  (id);

-- Index: comments_nid_idx

-- DROP INDEX comments_nid_idx;

CREATE INDEX comments_nid_idx
  ON comments
  USING btree
  (nid);

在comments_lemms中有800万个条目,在评论中 - 270万条。 我执行以下SQL查询:

update comments_lemms set bm25=(select lemm_length from comments where id=comment_id limit 1)

它需要超过20分钟的运行而且我会停止它,因为pgAdmin看起来就要崩溃了。 有没有办法修改这个查询或索引或我的数据库中的任何东西,以加快一些事情?我将来必须运行一些类似的查询,每个等待超过30分钟是非常痛苦的。

1 个答案:

答案 0 :(得分:1)

  

在comments_lemms中有800万个条目,在评论中 - 270万条。我执行以下SQL查询:

update comments_lemms set bm25=(select lemm_length from comments where id=comment_id limit 1)

换句话说,你正在通过8M条目,并且对于每一行,你正在使用索引循环进行嵌套循环。由于limit 1指令,PG不会重写/优化它。

请改为尝试:

update comments_lemms set bm25 = comments.lemm_length
from comments
where comments.id = comments_lemms.comment_id;

它应该执行两次seq扫描并将其哈希或合并连接在一起,然后一次性继续更新。