#mysql #sql #sql-server #oracle
#mysql #sql #sql-сервер #Oracle
Вопрос:
Чтобы проиллюстрировать мой вопрос, давайте рассмотрим пример с файлами журнала. Вы устанавливаете ограничение в байтах, и каждый байт, который проходит через него, удаляется, чтобы освободить место для новых записей.
Мне нужно что-то подобное для моей базы данных, и я хочу создать запрос, который будет выполняться ежедневно.
Запрос удалит все старые записи в таблице T выше числа записей N.
Записи будут отсортированы по дате, конечно, по убыванию.
В этой таблице несколько миллионов записей.
Комментарии:
1. Какую базу данных вы используете?
2. Извините за это, я добавил три самые популярные базы данных, которые используют наши клиенты.
Ответ №1:
If ID
является первичным ключом T:
delete T where ID not in (select top N ID from T order by date_column desc)
Комментарии:
1. Не думаете ли вы, что запрос идентификатора миллионов вызовет проблемы с производительностью?
2. Если в T.date_column есть индекс, а N не очень большое, то это должно быть довольно быстро.
Ответ №2:
Что-то вроде этого должно работать.
DELETE FROM <table> WHERE date < (
SELECT min(date) FROM (
SELECT date FROM table
ORDER BY date DESC
LIMIT N
)
)
Внутренний выбор находит верхние N новых записей.
Затем средний выбор находит более старую дату для них, а внешний выбор удаляет все, что старше этого.
Комментарии:
1. При этом вы можете оставлять больше
N
записей в исходной таблице, если есть несколько целых значений с одинаковой меткой времени. Однако это, по-видимому, довольно хорошее приближение, и для целей OP должно выполнять эту работу на самом деле.
Ответ №3:
Вы не указываете RDBMS. Для SQL Server
WITH CTE AS
(
SELECT ROW_NUMBER() OVER (ORDER BY Dt DESC) AS Rn
FROM T
)
DELETE FROM CTE
WHERE Rn > 100000
Ответ №4:
Если я правильно понял ваш вопрос, вам нужно что-то вроде
DELETE FROM T WHERE ID IN (SELECT TOP 1000 ID FROM T AS T1 WHERE T1.DATE > @DATE )
В этом примере N = 1000, а минимальная дата — @DATE
Комментарии:
1. это приведет к удалению строк, которые OP намеревается сохранить
Ответ №5:
Для ORACLE
delete from T
where rowid not in ( select rowid
from (select rowid from T order by date desc)
where rownum <= N
)
Комментарии:
1. Я был бы склонен использовать NOT EXISTS вместо NOT IN
Ответ №6:
Для Oracle (enterprise) вы можете рассмотреть возможность разбиения большой таблицы на диапазоны по дате. Затем вы можете удалить или обрезать разделы, которые вы хотите, очень легко (и быстро). Хотя это определенно не общее решение.