Я пытаюсь перенести некоторые старые запросы MySQL в PostgreSQL, но у меня проблемы с этим:
DELETE FROM logtable ORDER BY timestamp LIMIT 10;
PostgreSQL не допускает упорядочивания или ограничений в синтаксисе удаления, а таблица не имеет первичного ключа, поэтому я не могу использовать подзапрос. Кроме того, я хочу сохранить поведение, при котором запрос удаляет точно заданное число или записи - например, если таблица содержит 30 строк, но все они имеют одинаковую временную метку, я все равно хочу удалить 10, хотя это не имеет значения. который 10.
Так; как удалить фиксированное количество строк с сортировкой в PostgreSQL?
Изменить: отсутствие первичного ключа означает, что нет log_id
столбца или подобного. Ах, радости устаревших систем!
sql
postgresql
Что это
источник
источник
alter table foo add column id serial primary key
.Ответы:
Вы можете попробовать использовать
ctid
:Это
ctid
:Также есть,
oid
но он существует только в том случае, если вы специально попросите об этом при создании таблицы.источник
VACUUM FULL
или автовакууминг проблем , потому что если они изменяютctid
значения в таблице, запрос работает?ctid
документацияctid
достаточно стабильна, чтобы этот DELETE работал нормально, но не достаточно стабильна, чтобы, например, поместить в другую таблицу как гетто-FK. Предположительно, вы не ОБНОВЛЯЕТЕ,logtable
поэтому вам не нужно беспокоиться об этом измененииctid
s иVACUUM FULL
заблокировать таблицу ( postgresql.org/docs/current/static/routine-vacuuming.html ), поэтому вам не нужно беспокоиться о иначе этоctid
может измениться. PostgreSQL-Fu @araqnid довольно силен, и документация с ним согласна.Документы Postgres рекомендуют использовать массив вместо IN и подзапроса. Это должно работать намного быстрее
Этот и некоторые другие приемы можно найти здесь
источник
any (array( ... ));
быстрее, чемin ( ... )
это звучит как ошибка в оптимизаторе запросов - он должен уметь определять это преобразование и делать то же самое с самими данными.IN
наUPDATE
(который может быть разница).источник
Предполагая, что вы хотите удалить ЛЮБЫЕ 10 записей (без упорядочивания), вы можете сделать это:
Для моего варианта использования удаление 10 миллионов записей оказалось быстрее.
источник
Вы можете написать процедуру, которая перебирает цикл удаления для отдельных строк, процедура может принимать параметр, чтобы указать количество элементов, которые вы хотите удалить. Но это немного избыточно по сравнению с MySQL.
источник
Если у вас нет первичного ключа, вы можете использовать синтаксис массива Where IN с составным ключом.
Это сработало для меня.
источник