Tengo una tabla de Postgres con ~ 2.1 millones de filas. Ejecuté la siguiente actualización:
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;
Esta consulta tardó 39 horas en ejecutarse. Estoy ejecutando esto en un procesador de computadora portátil i7 Q720 de 4 núcleos (físico), mucha RAM, nada más funcionando la gran mayoría de las veces. Sin restricciones de espacio en el disco duro. La mesa había sido aspirada, analizada y reindexada recientemente.
Durante todo el tiempo en que se ejecutó la consulta, al menos después de que se WITH
completó la inicial , el uso de la CPU generalmente era bajo y el HDD estaba en uso al 100%. El HDD se usaba tan fuerte que cualquier otra aplicación funcionaba mucho más lentamente de lo normal.
La configuración de energía de la computadora portátil estaba en Alto rendimiento (Windows 7 x64).
Aquí está el EXPLICAR:
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
solo excluye unas pocas decenas de miles de filas. Incluso con esa WHERE
cláusula, sigo operando en más de 2 millones de filas.
El disco duro está encriptado con TrueCrypt 7.1a. Que ralentiza las cosas un poco, pero no lo suficiente para causar una consulta a tomar que muchas horas.
La WITH
parte solo tarda unos 3 minutos en ejecutarse.
El arrest_id
campo no tenía índice para clave externa. Hay 8 índices y 2 claves foráneas en esta tabla. Todos los demás campos de la consulta están indexados.
El arrest_id
campo no tenía restricciones excepto NOT NULL
.
La tabla tiene 32 columnas en total.
arrest_id
Es de tipo carácter variable (20) . Me doy cuenta de que rank()
produce un valor numérico, pero tengo que usar caracteres que varían (20) porque tengo otras filas citing_jurisdiction<>1
que usan datos no numéricos para este campo.
El arrest_id
campo estaba en blanco para todas las filas con citing_jurisdiction=1
.
Este es un portátil personal de alta gama (desde hace 1 año). Soy el único usuario. No se estaban ejecutando otras consultas u operaciones. El bloqueo parece poco probable.
No hay desencadenantes en ningún lugar de esta tabla ni en ningún otro lugar de la base de datos.
Otras operaciones en esta base de datos nunca toman una cantidad de tiempo anormal. Con una indexación adecuada, las SELECT
consultas suelen ser bastante rápidas.
Seq Scan
son un poco atemorizantes ...