Estou tentando portar algumas consultas MySQL antigas para PostgreSQL, mas estou tendo problemas com esta:
DELETE FROM logtable ORDER BY timestamp LIMIT 10;
O PostgreSQL não permite ordenação ou limites em sua sintaxe de exclusão, e a tabela não possui uma chave primária, então não posso usar uma subconsulta. Além disso, quero preservar o comportamento em que a consulta exclui exatamente o número ou os registros fornecidos - por exemplo, se a tabela contém 30 linhas, mas todos têm o mesmo carimbo de data / hora, ainda quero excluir 10, embora não importe quais 10.
Assim; como excluo um número fixo de linhas com classificação no PostgreSQL?
Editar: Sem chave primária significa que não há log_id
coluna ou similar. Ah, as alegrias dos sistemas legados!
sql
postgresql
O que é isso
fonte
fonte
alter table foo add column id serial primary key
.Respostas:
Você pode tentar usar
ctid
:O
ctid
é:Há também
oid
mas isso só existe se você solicitar especificamente quando criar a mesa.fonte
VACUUM FULL
ou autovacuum causar problemas se eles alterarem osctid
valores na tabela durante a execução da consulta?ctid
documentação é quectid
é estável o suficiente para fazer esse DELETE funcionar bem, mas não estável o suficiente para, por exemplo, colocar em outra mesa como um gueto-FK. Provavelmente, você não atualizar ologtable
que você não precisa se preocupar com que a mudançactid
s eVACUUM FULL
faz bloquear a tabela ( postgresql.org/docs/current/static/routine-vacuuming.html ), assim você não precisa se preocupar com a outra maneira que issoctid
pode mudar. O PostgreSQL-Fu de @araqnid é muito forte e os documentos concordam com ele.A documentação do Postgres recomenda usar array em vez de IN e subconsulta. Isso deve funcionar muito mais rápido
Este e alguns outros truques podem ser encontrados aqui
fonte
any (array( ... ));
for mais rápido do quein ( ... )
isso, parece um bug no otimizador de consulta - ele deve ser capaz de detectar essa transformação e fazer a mesma coisa com os próprios dados.IN
em umUPDATE
(o que pode ser a diferença).fonte
Supondo que você deseja excluir QUALQUER 10 registros (sem o pedido), você pode fazer isso:
Para o meu caso de uso, excluir registros de 10 milhões, isso acabou sendo mais rápido.
fonte
Você pode escrever um procedimento que faz um loop sobre a exclusão de linhas individuais, o procedimento pode receber um parâmetro para especificar o número de itens que deseja excluir. Mas isso é um pouco exagero em comparação com o MySQL.
fonte
Se você não tem uma chave primária, pode usar a sintaxe Where IN da matriz com uma chave composta.
Isso funcionou para mim.
fonte