Estoy tratando de transferir algunas consultas de MySQL antiguas a PostgreSQL, pero tengo problemas con esta:
DELETE FROM logtable ORDER BY timestamp LIMIT 10;
PostgreSQL no permite pedidos o límites en su sintaxis de eliminación, y la tabla no tiene una clave principal, por lo que no puedo usar una subconsulta. Además, quiero conservar el comportamiento en el que la consulta elimina exactamente el número o los registros dados; por ejemplo, si la tabla contiene 30 filas pero todas tienen la misma marca de tiempo, todavía quiero eliminar 10, aunque no importa cual 10.
Entonces; ¿Cómo elimino un número fijo de filas con la clasificación en PostgreSQL?
Editar: Sin clave principal significa que no hay log_id
columna o similar. ¡Ah, el placer de los sistemas heredados!
sql
postgresql
Que es eso
fuente
fuente
alter table foo add column id serial primary key
.Respuestas:
Podría intentar usar
ctid
:El
ctid
es:También existe,
oid
pero eso solo existe si lo solicita específicamente cuando crea la tabla.fuente
VACUUM FULL
o el autovacío cause problemas si cambian losctid
valores en la tabla mientras se ejecuta la consulta?ctid
documentación es quectid
es lo suficientemente estable como para que este DELETE funcione bien, pero no lo suficientemente estable como para, por ejemplo, poner en otra tabla como ghetto-FK. Es de suponer que no ACTUALIZA el,logtable
por lo que no tiene que preocuparse por los cambiosctid
yVACUUM FULL
bloquea la tabla ( postgresql.org/docs/current/static/routine-vacuuming.html ) para que no tenga que preocuparse por de la otra manera esoctid
puede cambiar. PostgreSQL-Fu de @ araqnid es bastante fuerte y los docs están de acuerdo con él.Los documentos de Postgres recomiendan usar una matriz en lugar de IN y subconsulta. Esto debería funcionar mucho más rápido
Este y otros trucos se pueden encontrar aquí.
fuente
any (array( ... ));
es más rápido quein ( ... )
eso, suena como un error en el optimizador de consultas, debería poder detectar esa transformación y hacer lo mismo con los datos en sí.IN
en unUPDATE
(lo que podría ser la diferencia).fuente
Suponiendo que desea eliminar CUALQUIER 10 registros (sin el pedido), puede hacer esto:
Para mi caso de uso, eliminar 10 millones de registros, resultó ser más rápido.
fuente
Puede escribir un procedimiento que recorra la eliminación de líneas individuales, el procedimiento podría tomar un parámetro para especificar la cantidad de elementos que desea eliminar. Pero eso es un poco exagerado en comparación con MySQL.
fuente
Si no tiene una clave principal, puede usar la sintaxis de la matriz Where IN con una clave compuesta.
Esto funcionó para mí.
fuente