У меня есть таблица Postgres с ~ 2,1 миллиона строк. Я запустил обновление ниже:
WITH stops AS (
SELECT id,
rank() OVER (ORDER BY offense_timestamp,
defendant_dl,
offense_street_number,
offense_street_name) AS stop
FROM consistent.master
WHERE citing_jurisdiction=1
)
UPDATE consistent.master
SET arrest_id=stops.stop
FROM stops
WHERE master.id = stops.id;
Этот запрос занял 39 часов. Я использую это на 4-х (физическом) процессоре для ноутбука i7 Q720, много оперативной памяти, больше ничего не работает в большинстве случаев. Нет места на жестком диске. Стол был недавно очищен, проанализирован и переиндексирован.
Все время выполнения запроса, по крайней мере, после первоначального WITH
завершения, загрузка ЦП обычно была низкой, а жесткий диск использовался на 100%. Жесткий диск использовался так сильно, что любое другое приложение работало значительно медленнее, чем обычно.
Настройки питания ноутбука были на высокой производительности (Windows 7 x64).
Вот ОБЪЯСНЕНИЕ:
Update on master (cost=822243.22..1021456.89 rows=2060910 width=312)
CTE stops
-> WindowAgg (cost=529826.95..581349.70 rows=2060910 width=33)
-> Sort (cost=529826.95..534979.23 rows=2060910 width=33)
Sort Key: consistent.master.offense_timestamp, consistent.master.defendant_dl, consistent.master.offense_street_number, consistent.master.offense_street_name
-> Seq Scan on master (cost=0.00..144630.06 rows=2060910 width=33)
Filter: (citing_jurisdiction = 1)
-> Hash Join (cost=240893.51..440107.19 rows=2060910 width=312)
Hash Cond: (stops.id = consistent.master.id)
-> CTE Scan on stops (cost=0.00..41218.20 rows=2060910 width=48)
-> Hash (cost=139413.45..139413.45 rows=2086645 width=268)
-> Seq Scan on master (cost=0.00..139413.45 rows=2086645 width=268)
citing_jurisdiction=1
исключает только несколько десятков тысяч строк. Даже с этим WHERE
условием я все еще работаю над более чем 2 миллионами строк.
Жесткий диск полностью зашифрован с помощью TrueCrypt 7.1a. То , что замедляет немного, но не достаточно , чтобы вызвать запрос , чтобы принять , что много часов.
WITH
Часть занимает около 3 минут для запуска.
arrest_id
Поле не было никакого индекса внешнего ключа. В этой таблице 8 индексов и 2 внешних ключа. Все остальные поля в запросе индексируются.
arrest_id
Поле не было никаких ограничений , кроме NOT NULL
.
Всего в таблице 32 столбца.
arrest_id
имеет тип символов, меняющихся (20) . Я понимаю, что rank()
производит числовое значение, но я должен использовать переменный символ (20), потому что у меня есть другие строки, где citing_jurisdiction<>1
используются не числовые данные для этого поля.
arrest_id
Поле было пустым для всех строк с citing_jurisdiction=1
.
Это персональный, высококлассный (по состоянию на 1 год назад) ноутбук. Я единственный пользователь. Другие запросы или операции не выполнялись. Блокировка кажется маловероятной.
В этой таблице или в другом месте базы данных нет триггеров.
Другие операции с этой базой данных никогда не занимают много времени. При правильной индексации SELECT
запросы обычно выполняются довольно быстро.
Seq Scan
немного страшно ...