Pregunta

He estado ejecutando una ACTUALIZACIÓN en una tabla que contiene 250 millones de filas con 3 índices '; esta ACTUALIZACIÓN utiliza otra tabla que contiene 30 millones de filas. Ha estado funcionando durante aproximadamente 36 horas ahora. Me pregunto si esta es una manera de descubrir qué tan cerca está de hacerse, ya que si planea demorar un millón de días en hacerlo, lo mataré; sin embargo, si solo necesita uno o dos días, lo dejaré correr. Aquí está el comando-consulta:

UPDATE pagelinks SET pl_to = page_id
    FROM page
    WHERE 
        (pl_namespace, pl_title) = (page_namespace, page_title)
        AND
        page_is_redirect = 0
;

EXPLAIN no es el problema aquí y solo menciono que la tabla grande tiene múltiples índices para justificar de alguna manera el tiempo que lleva ACTUALIZARLA. Pero aquí está el EXPLICACIÓN de todos modos:

Merge Join  (cost=127710692.21..135714045.43 rows=452882848 width=57)
  Merge Cond: (("outer".page_namespace = "inner".pl_namespace) AND ("outer"."?column4?" = "inner"."?column5?"))
  ->  Sort  (cost=3193335.39..3219544.38 rows=10483593 width=41)
        Sort Key: page.page_namespace, (page.page_title)::text
        ->  Seq Scan on page  (cost=0.00..439678.01 rows=10483593 width=41)
              Filter: (page_is_redirect = 0::numeric)
  ->  Sort  (cost=124517356.82..125285665.74 rows=307323566 width=46)
        Sort Key: pagelinks.pl_namespace, (pagelinks.pl_title)::text"
        ->  Seq Scan on pagelinks  (cost=0.00..6169460.66 rows=307323566 width=46)

Ahora también envié un comando de consulta paralelo para DROP uno de los índices de pagelinks '; por supuesto, está esperando que finalice la ACTUALIZACIÓN (¡pero de todas formas me dio ganas de intentarlo!). Por lo tanto, no puedo SELECCIONAR nada de pagelinks por temor a corromper los datos (¿a menos que piense que sería seguro matar el proceso de postmaster de DROP INDEX?).

Así que me pregunto si es una tabla que mantendría un registro de la cantidad de tuplas muertas o algo así. Sería bueno saber qué tan rápido o qué tan lejos está la ACTUALIZACIÓN en la finalización de su tarea.

Thx (PostgreSQL no es tan inteligente como pensaba; necesita heurística)

¿Fue útil?

Solución

¿Leíste la documentación de PostgreSQL para " Uso de EXPLAIN " ;, para interpretar el resultado que está mostrando?

No soy un usuario habitual de PostgreSQL, pero acabo de leer ese documento y luego lo comparo con la salida EXPLAIN que está mostrando. Su consulta de UPDATE parece no utilizar índices, y se ve obligada a realizar escaneos de tabla para ordenar la página y pagelinks . Sin duda, el tipo es lo suficientemente grande como para necesitar archivos de disco temporales, que creo que se crean en su temp_tablespace .

Luego veo las páginas estimadas de la base de datos leídas. El nivel superior de esa salida EXPLAIN dice (cost = 127710692.21..135714045.43) . Las unidades aquí están en accesos de E / S de disco. Por lo tanto, accederá al disco más de 135 millones de veces para hacer esto UPDATE .

Tenga en cuenta que incluso los discos de 10,000 rpm con un tiempo de búsqueda de 5 ms pueden lograr al menos 200 operaciones de E / S por segundo en condiciones óptimas. Esto significaría que su UPDATE tomaría 188 horas (7.8 días) de E / S de disco, incluso si pudiera mantener la E / S de disco saturada durante ese período (es decir, lecturas / escrituras continuas sin interrupciones) . Esto es imposible, y esperaría que el rendimiento real fuera al menos un orden de magnitud, especialmente porque sin duda ha estado usando este servidor para todo tipo de otros trabajos mientras tanto. Así que supongo que solo estás a una fracción del camino a través de tu UPDATE .

Si fuera yo, habría eliminado esta consulta el primer día y encontrado otra forma de realizar el UPDATE que hizo un mejor uso de los índices y no requirió clasificación en disco. Probablemente no pueda hacerlo en una sola declaración SQL.

En cuanto a su DROP INDEX , creo que simplemente está bloqueando, esperando un acceso exclusivo a la mesa, y mientras esté en este estado, creo que probablemente pueda matarlo.

Otros consejos

Esto es muy antiguo, pero si quieres una forma de monitorear tu actualización ... Recuerda que las secuencias se ven afectadas globalmente, así que puedes crear una para monitorear esta actualización en otra sesión al hacer esto:

create sequence yourprogress; 

UPDATE pagelinks SET pl_to = page_id
    FROM page
    WHERE 
        (pl_namespace, pl_title) = (page_namespace, page_title)
        AND
        page_is_redirect = 0 AND NEXTVAL('yourprogress')!=0;

Luego, en otra sesión, simplemente haga esto (no se preocupe por las transacciones, ya que las secuencias se ven afectadas globalmente):

select last_value from yourprogress;

Esto mostrará cuántas líneas están siendo afectadas, por lo que puede estimar cuánto tiempo llevará.

Al final, reinicia tu secuencia para hacer otro intento:

alter sequence yourprogress restart with 1;

O simplemente suéltalo:

drop sequence yourprogress;

Necesita índices o, como señaló Bill, tendrá que realizar exploraciones secuenciales en todas las tablas.

CREATE INDEX page_ns_title_idx on page(page_namespace, page_title);
CREATE INDEX pl_ns_title_idx on pagelink(pl_namespace, pl_title);
CREATE INDEX page_redir_idx on page(page_is_redirect);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top