У мене є таблиця 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%. HDD використовувався настільки важко, що будь-який інший додаток працював значно повільніше, ніж зазвичай.
Налаштування живлення ноутбука були на високому рівні (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трохи страшно ...