У меня есть таблица, как это (больше столбцов, но они будут делать):Postgres - UPDATE становится медленнее, с течением времени
events
+----------+----------------+--------------------+------------------+------------------+---------+
| event_id | user_ipaddress | network_userid | domain_userid | user_fingerprint | user_id |
+----------+----------------+--------------------+------------------+------------------+---------+
| 1 | 127.0.0.1 | 000d7d9e-f3cb-4a08 | 26dc9870c3572519 | 2199066221 | |
| 2 | 127.0.0.1 | 000d7d9e-f3cb-4a08 | 26dc9870c3572519 | 2199066221 | |
| 3 | 127.0.0.1 | 000d7d9e-f3cb-4a08 | 26dc9870c3572519 | 2199066221 | |
| 4 | 127.0.0.1 | 000d7d9e-f3cb-4a08 | 26dc9870c3572519 | 2199066221 | |
+----------+----------------+--------------------+------------------+------------------+---------+
таблица содержит около 1M записей. Я пытаюсь обновить все записи, чтобы установить user_id
.
Для этого я использую очень простой PHP-скрипт.
Я цикл по каждой записи с user_id = NULL
и SELECT
из всей таблицы, чтобы найти существующий user_id
на основе user_ipaddress
, network_userid
, domain_userid
и/или user_fingerprint
.
Если ничего не найдено, я сгенерирую уникальный отчет user_id
и UPDATE
.
Если матч был найден, я сделаю UPDATE
запись с корреспондентом user_id
.
Запрос выглядит следующим образом:
UPDATE events SET user_id = 'abc' WHERE event_id = '1'
SELECT
часть супер быстро (~ 5 мс).
Часть UPDATE
начинается быстро (~ 10 мс), но становится медленнее (~ 800 мс) после нескольких сотен обновлений.
Если я жду около 10-20 минут, он снова станет быстрым.
Я использую PostgreSQL 9.3.3 на AWS RDS (db.m1.medium) с общим хранилищем SSD. У меня есть индексы по всем столбцам, объединенные и индивидуально.
Я играл с FILLFACTOR
и в настоящее время он устанавливается на 70
. Я попытался запустить VACUUM FULL events
, но я никогда не знаю, закончилось ли это (ждали более 1 часа). Также я пробовал REINDEX TABLE events
.
Я единственный, кто пользуется этим сервером.
Вот EXPLAIN ANALYZE
из UPDATE
запроса:
Update on events (cost=0.43..8.45 rows=1 width=7479) (actual time=0.118..0.118 rows=0 loops=1)
-> Index Scan using events_event_id_idx on events (cost=0.43..8.45 rows=1 width=7479) (actual time=0.062..0.065 rows=1 loops=1)
Index Cond: (event_id = '1'::bpchar)
Total runtime: 0.224 ms
Любые хорошие идеи о том, как я могу сохранить запрос быстро?
Можете ли вы показать «EXPLAIN ANALYZE» на длинном «UPADATE»? –
"cost = 0.43..8.45" hmmm .... [См. Слайд 13] (https://wiki.postgresql.org/images/4/45/Explaining_EXPLAIN.pdf) – bishop
@IgorRomanchenko, в моем вопросе есть длинный индекс UPDATE –