Как удалить все, кроме последних 20 000 записей в MS SQL 2005? - PullRequest
6 голосов
/ 13 ноября 2008

Каждую ночь мне нужно обрезать таблицу, чтобы в ней были только последние 20 000 записей. Я мог бы использовать подзапрос:

delete from table WHERE id NOT IN (select TOP 20000 ID from table ORDER BY date_added DESC)

Но это кажется неэффективным, особенно если мы позже решим сохранить 50 000 записей. Я использую SQL 2005, и думал, что я мог бы использовать ROW_NUMBER () OVER как-нибудь сделать это? Закажите их и удалите все, у которых ROW_NUMBER больше 20 000? Но я не мог заставить его работать. Является ли подзапрос моей лучшей ставкой или есть лучший способ?

Ответы [ 6 ]

7 голосов
/ 13 ноября 2008

Если это просто кажется неэффективным, я бы удостоверился, что оно неэффективно, прежде чем я начну лаять неправильное дерево.

Измерьте время, загрузку процессора, дисковый ввод-вывод и т. Д., Чтобы увидеть, насколько хорошо он работает. Я думаю, вы найдете, что он работает лучше, чем вы думаете.

3 голосов
/ 13 ноября 2008
DECLARE @limit INT
SELECT @limit = min(id) FROM
   (SELECT TOP 20000 id FROM your_table ORDER BY id DESC)x
DELETE FROM your_table where id < @limit

Смысл состоял в том, чтобы избежать вложенного запроса, который я могу или не могу оптимизировать (извините, не sql guru.)

3 голосов
/ 13 ноября 2008

Конечно, ваш пробег будет отличаться - это будет зависеть от того, сколько реальных записей вы вычеркиваете из нижней части этой таблицы, но вот альтернатива.

Примечание: поскольку у вас есть поле "Date_Added", стоит ли просто сохранять дату и время последнего запуска и использовать это в предложении where для фильтрации записей, которые нужно удалить? Теперь вместо 20 000 записей разрешите количество дней в журнале X ... Просто мысль ...


- Получите записи, которые мы хотим сохранить в темп.
- Вы можете классифицировать хранителей, как пожелаете.

select top 20000 * into #myTempTable from MyTable ORDER BY DateAdded DESC

- Использование truncate не уничтожает наш лог-файл и использует меньше системных ресурсов ...

truncate table MyTable 

- Верните наши «сохраненные» записи обратно в ствол ...
- Предполагается, что вы НЕ используете столбец идентификаторов - если вы используете,
- укажите имена полей вместо '*' и сделайте что-то вроде
- SET IDENTITY_INSERT MyTable ON
- вставить в MyTable выбрать field1, field2, field3 из #myTempTable
- (Я думаю, что это правильно)

insert into MyTable select * from #myTempTable

- будь хорошим гражданином.

drop table #myTempTable

1020 *
*

Надеюсь, это поможет -

1 голос
/ 16 декабря 2012

вставить 20000 во временную таблицу, затем удалить все записи из основной таблицы, затем снова вставить 20000 записей из временной таблицы в основную таблицу ..,

0 голосов
/ 13 ноября 2008

Ваш вопрос подразумевает, что вы обрезаете, чтобы получить лучшую дневную производительность из таблицы. Получаете ли вы сканирование таблицы по дневным запросам? Разве лучшие индексы не будут ответом? Или вы находитесь в ситуации, когда вы застряли с "дрянной схемой"?

Или у вас действительно странная ситуация, когда вам действительно нужно удалить старые записи? 20 000 - сложное и быстрое число? Или может сработать свидание? Тогда и индекс по столбцу datetime сделает обрезку немного проще.

0 голосов
/ 13 ноября 2008

Конечно, это основной случай для включения в процедуру и использования двух операторов SQL - первый, чтобы выбрать последний идентификатор и вычесть 20 000, затем второй, чтобы удалить все строки с идентификатором ниже, чем этот.

Однако на первый взгляд это звучит так, как будто вы столкнетесь с большой фрагментацией этого подхода, и это может быть хорошим аргументом для создания новой таблицы, вставки в нее последних 20 000 записей удаляя старый и переименовывая новый. Возможно, даже стоит поместить таблицу в другую базу данных и создать представление из основной базы данных для облегчения доступа. Я обычно склонен делать это с таблицами, используемыми для загрузки данных и аудита.

Очень трудно сказать, не зная ваших реальных объемов данных и поведения, но вполне может быть, что в целом ваша неэффективность будет в большей степени обусловлена ​​этим, чем используемым вами методом удаления. Если вы собираете только тысячу или менее записей в день, удаление, вероятно, в порядке с выполнением плана обслуживания по оптимизации данных, но больше, и я хотел бы рассмотреть более радикальный подход.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...