Очень медленное обновление относительно небольшой таблицы в PostgreSQL - PullRequest
0 голосов
/ 26 мая 2011

Ну, у меня есть следующая таблица (информация от 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 8 миллионов записей, в комментариях - 270 тысяч. Я выполняю следующий SQL-запрос:

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

И это занимает более 20 минут работы, и я прекращаю его, потому что pgAdmin выглядит так, как будто он вот-вот потерпит крах. Есть ли способ изменить этот запрос или индексы или что-то еще в моей базе данных, чтобы немного ускорить процесс? В будущем мне придется выполнить несколько похожих запросов, и довольно больно ждать более 30 минут для каждого.

1 Ответ

1 голос
/ 26 мая 2011

в comments_lemms 8 миллионов записей, в комментариях - 270 тысяч. Я выполняю следующий SQL-запрос:

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

Другими словами, вы заставляете его проходить 8 миллионов записей, и для каждой строки вы делаете вложенный цикл с циклом индекса. PG не будет переписывать / оптимизировать его из-за инструкции limit 1.

Попробуйте вместо этого:

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

Он должен выполнить два последовательных сканирования и объединить их в хэш или объединить, а затем продолжить обновление за один раз.

...