Postgres 9 супер медленное простое удаление - PullRequest
8 голосов
/ 24 октября 2011

У меня есть солидная база данных ... не очень большая - всего около 1 ГБ данных.

Мне нужно удалить несколько строк из нескольких таблиц. Например у меня есть таблица

 Order
 id     | ... | status   | ...
 1      | ... | 1        | ...
 ...
 40     | ... | 20       | ...
 41     | ... | 1        | ...
 ...
 470000 | ... | 12       | ...

Теперь я хочу удалить все заказы, которые имеют status=1

Полагаю, я делаю это с:

УДАЛИТЬ ИЗ ЗАКАЗА, ГДЕ состояние = 1

Казалось бы, все красиво и просто, но на это уходит много времени! Когда я запустил этот запрос, он все еще работал на 100% загрузки ЦП через 40 минут ... когда я завершил процесс, ничего не было удалено.

Когда я пытался ограничить область с помощью

УДАЛИТЬ ИЗ ЗАКАЗА, ГДЕ состояние = 1 И id <1000 </p>

понадобилось несколько минут, чтобы удалить около 200 строк ....

Что-то мне не хватает в моей конфигурации? Что-нибудь, что я должен искать / проверить / изменить? Есть идеи, почему это чертовски неэффективно?

Позвольте мне добавить, что я обычно работаю с MySQL и мне нужно управлять этой базой данных postgres, но на самом деле у меня нет опыта работы с postgres, поэтому это может быть что-то очень простое.

Индексы находятся в столбцах id и status.

Таблица содержит около 500 тыс. Строк, около половины необходимо удалить.

План выполнения:

Delete  (cost=0.00..19474.19 rows=266518 width=6)
->  Seq Scan on Orders  (cost=0.00..19474.19 rows=266518 width=6)
Filter: (statusid = 1)

Нет никаких триггеров или правил любого рода. Более того, я не добавил, что это свежая копия таблицы, я имею в виду, что она была перенесена с другого сервера с экспортом / импортом. Возможно, это как-то играет роль?

Поможет ли удаление индексов?

Ответы [ 2 ]

8 голосов
/ 24 октября 2011

Ничто не удалено после того, как вы убили процесс, это ТОЧНО то, что вы должны увидеть.

Удаление происходит как транзакция, то есть либо все удалено, либо ничего нет.Чтобы убедиться, что это может произойти, строки должны быть скопированы куда-то перед их удалением.Это означает, что удаление 250 тыс. Строк занимает примерно столько же времени, сколько и вставка такого количества строк.В некоторых случаях может быть быстрее создать новую таблицу со всем НЕ УДАЛЕННЫМ и переименовать новую таблицу в старую.

Если это переносится из другой БД, вам, вероятно, будет лучше, если вы сможетеВо-первых, не вставляйте строки из 250 000.

(Это общая мудрость СУРБД, а не специфичная для postgresql - детали того, как работает postgres MVCC, могут существенно отличаться.)

2 голосов
/ 24 апреля 2015

Гораздо быстрее использовать COPY FROM / TURNCATE / COPY TO для больших таблиц.

Но, конечно, вы должны быть осторожны со ссылками и, если возможно, отключить триггеры.

...