Postgresql: оптимизировать обновление с помощью соединения - PullRequest
0 голосов
/ 19 ноября 2018

Мне нужно обновить таблицу Postgres, которая содержит много строк.Чтобы оптимизировать его, нужно вычислить некоторые поля во временной таблице, а затем обновить мою основную таблицу с результатами.

Последний шаг (обновление основной таблицы) может быть очень медленным при наличии миллионов строкв моем столе.Это делается с помощью:

UPDATE mytable 
   SET myfield=tmp_mytable.myfield, 
       myfieldtwo=tmp_mytable.myfieldtwo  
FROM tmp_mytable 
WHERE mytable.mypk = tmp_mytable.mypk;

Обновление выполняется в пакете, поэтому я создаю tmp_mytable с 10 000 строк, а затем обновляю только 10 000 mytable одновременно.

Когда строк мало (<5 миллионов), требуется всего несколько секунд.Но при более чем 10 миллионах каждой итерации требуется от 15 до 30 секунд. </p>

Насколько я понимаю, медлительность связана с обновлением индекса (поскольку postgres создает внутреннюю новую строку при каждом обновлении, которую необходимо переиндексировать).Однако мне нужны индексы для того, чтобы вычислить некоторые из «myfields», также для эффективного объединения.

При необходимости я создаю индексы с

CREATE INDEX CONCURRENTLY on mytable(myfield)

Но CONCURRENTLY бесполезен для производительности.

Есть ли какой-нибудь совет, чтобы ускорить обновление, или, возможно, избегайте пересчета индексов (они не нужны для моих вычислений)?

РЕДАКТИРОВАТЬ: ОБЪЯСНЕНИЕ окончательного обновления

Update on mytable  (cost=0.42..61854.23 rows=8265 width=732)
  ->  Nested Loop  (cost=0.42..61854.23 rows=8265 width=732)
    ->  Seq Scan on tmp_mytable  (cost=0.00..517.65 rows=8265 width=270)
    ->  Index Scan using mytable_pkey on mytable  (cost=0.42..7.41 rows=1 width=580)
          Index Cond: ((mytable_id)::text = (tmp_scene. mytable_id)::text)
...