Tengo un problema de rendimiento con las secuencias DELETE/INSERT en PostgreSQL 9.0. Estoy buscando ideas para mejorar la situación.PostgreSQL DELETE/INSERT throughput issue
En el hardware disponible para nosotros, puedo INSERTAR nuevas filas en una base de datos a una tasa sostenida de 3000/s (uniformemente en 10 tablas) más allá de las filas de 1m en cada tabla que usualmente pruebo. Sin embargo, si cambio a un modo donde ELIMINAR una fila y volver a INSERTARLO con datos diferentes, el rendimiento disminuye en más de un orden de magnitud a 250 filas/s (de nuevo, de manera uniforme en 10 tablas).
No hay restricciones en ninguna tabla. Hay 2 columnas indexadas en cada tabla con un tamaño de índice total (en 1m filas por tabla) de 1GB que se encuentra cómodamente dentro de shared_buffers (2GB). El tamaño total de los datos (en 1m filas por tabla) es de 12GB, que es mucho menor que la RAM total del sistema. Esta es una base de datos en la que podemos reconstruir en caso de emergencia, por lo que corremos con fsync apagado.
Parece que cuando estamos en el modo de llenado, nos beneficiamos de tiempos de búsqueda de disco muy bajos porque se anexan datos. Sin embargo, cuando cambiamos al modo de actualización, hay muchas búsquedas en curso (para eliminar las filas anteriores, presumiblemente). El disco aleatorio busca un costo de ~ 8ms (= ~ 125 por segundo). ¿Hay alguna manera (sin un cambio de hardware) de que podamos mejorar significativamente el rendimiento de las operaciones UPDATE/re-INSERT?
EDIT1: Estoy realizando pruebas de rendimiento en dos plataformas de hardware de especificaciones diferentes. Los números que cité anteriormente eran de la plataforma de especificaciones más altas. Acabo de completar una prueba en la plataforma de especificaciones más baja. En esta prueba inserto nuevas filas lo más rápido posible, registrando la tasa de inserción cada 10 segundos, hasta que he insertado 1 millón de filas. En este punto, mi script de prueba cambia a la actualización de filas aleatorias.
Este gráfico muestra la velocidad de actualización medido fue de ~ 150 cambios a los 10 cuadros/segundo durante población y la tasa de actualización se < 10 cambios a los 10 cuadros/segundo.
@wildplasser - La máquina es una máquina real, no una máquina virtual. Las 10 tablas tienen el siguiente esquema.
CREATE TABLE objecti_servicea_item1
(
iss_scs_id text,
iss_generation bigint,
boolattr1 boolean,
boolattr2 boolean,
boolattr3 boolean,
boolattr4 boolean,
boolattr5 boolean,
boolattr6 boolean,
boolattr7 boolean,
boolattr8 boolean,
boolattr9 boolean,
boolattr10 boolean,
boolattr11 boolean,
boolattr12 boolean,
boolattr13 boolean,
boolattr14 boolean,
boolattr15 boolean,
boolattr16 boolean,
boolattr17 boolean,
intattr1 bigint,
intattr2 bigint,
intattr3 bigint,
intattr4 bigint,
intattr5 bigint,
intattr6 bigint,
intattr7 bigint,
intattr8 bigint,
intattr9 bigint,
intattr10 bigint,
intattr11 bigint,
intattr12 bigint,
intattr13 bigint,
intattr14 bigint,
intattr15 bigint,
intattr16 bigint,
intattr17 bigint,
strattr1 text[],
strattr2 text[],
strattr3 text[],
strattr4 text[],
strattr5 text[],
strattr6 text[],
strattr7 text[],
strattr8 text[],
strattr9 text[],
strattr10 text[],
strattr11 text[],
strattr12 text[],
strattr13 text[],
strattr14 text[],
strattr15 text[],
strattr16 text[],
strattr17 text[]
)
WITH (
OIDS=FALSE
);
CREATE INDEX objecti_servicea_item1_idx_iss_generation
ON objecti_servicea_item1
USING btree
(iss_generation);
CREATE INDEX objecti_servicea_item1_idx_iss_scs_id
ON objecti_servicea_item1
USING btree
(iss_scs_id);
Las "Actualizaciones" que se realizan incluyen el siguiente SQL para cada una de las 10 tablas.
DELETE FROM ObjectI_ServiceA_Item1 WHERE iss_scs_id = 'ObjUID39'
INSERT INTO ObjectI_ServiceA_Item1
VALUES ('ObjUID39', '2', '0', NULL, '0'
, NULL, NULL, NULL, '1', '1', NULL, '0'
, NULL, NULL, NULL, NULL, '0', '1', '1'
, '-70131725335162304', NULL, NULL, '-5241412302283462832'
, NULL, '310555201689715409', '575266664603129486'
, NULL, NULL, NULL, NULL, NULL, NULL
, '-8898556182251816700', NULL, '3325820251460628173'
, '-3434461681822953613'
, NULL
, E'{pvmo2mt7dma37roqpuqjeu4p8b,"uo1kjt1b3eu9g5vlf0d02l6iaq\\\\\\",",45kfns1j80gc7fri0dm29hnrjo}'
, NULL, NULL
, E'{omjv460do8cb7abn8t3eg5b6ki,"a7hrlninbk1rmu6h3rd4787l7f\\\\\\",",24n3ipfua5spma2vrj2aji98g3}'
, NULL
, E'{1821v2n2ermm4jujrucu5tekmm,"ukgst224964uhthkhjj9v189ft\\\\\\",",6dfsaniq9mftvbdr8g1sr8e6as}'
, E'{c2a9gvf0fnd38m8vprlhkp2n74,"ts86vbat12lfr0d7l4tc29k9uk\\\\\\",",32b5j9r5evmrie4h21hi10dpot}'
, E'{18pve4cmcbrjiom9bpvoo1l4n0,"hrqcsane6r0n7u2oj79bj605rh\\\\\\",",32q5n18q3qbkuit605fv47270o}'
, E'{l3bf96shrpnnqgt35m7574t5n4,"cpol4k8296hbdqc9kac79oj0ua\\\\\\",",eqioulmb7vav10lbnc5jg752df}'
, E'{5fai108h163hpjcv0ofgfi7c28,"ci958009ddak3li7bp37slcs8i\\\\\\",",2itstj01tkprlul8f530uhs6s2}'
, E'{ueqfkdold8vc84jllr4b2cakt5,"t5vbea4r7tva091pa8j6886t60\\\\\\",",ul82aovhil1lpd290s14vd0p3i}'
, NULL, NULL, NULL, NULL, NULL)
Tenga en cuenta que durante la primera fase de mi prueba de rendimiento, el comando ELIMINAR siempre no hará nada.
@Frank Heikens - En la prueba de rendimiento que estoy ejecutando las actualizaciones se están realizando a partir de 10 hilos. Sin embargo, las actualizaciones se asignan a los hilos de una manera que garantiza que múltiples actualizaciones en la misma fila siempre sean manejadas por el mismo hilo.
¿Es esta una VM o una máquina real? También agregue (un fragmento de) la definición de la tabla && query, y el plan de consulta resultante a la pregunta. – wildplasser
¿Revisaste por cerraduras? Múltiples procesos podrían intentar eliminar el mismo registro. –
He editado mi publicación para responder a su comentario. – mchr