#sql #sql-server #datetime #greatest-n-per-group #sql-delete
#sql #sql-сервер #дата и время #наибольшее число на группу #sql-удалить
Вопрос:
Я пытаюсь найти самый быстрый способ удалить данные из моей таблицы. Моя логика заключается в том, чтобы иметь только последние 2 дня данных в Table1 для данного Lot_ID, а ID является уникальным первичным ключом в таблице.
Моих данных немного, но для выполнения приведенного ниже запроса мне все равно требуется около 8-9 минут.
WITH CTE AS
(
select t.ID
from (select t1.*,
DENSE_RANK() over (partition by Lot_ID order by TRY_CONVERT(DATE, DATEADD(second, t1.starttime, '19700101') )
desc) as seqnum
from Table1 t1
) t
where seqnum >2
)
DELETE Table1 WHERE EXISTS(select 1 from CTE where CTE.ID = Table1.ID )
Есть ли самый быстрый или лучший подход для этого?
Комментарии:
1. временные таблицы могут сделать это за вас (с периодом хранения для таблицы истории)
Ответ №1:
Вы можете попробовать удалить непосредственно из cte, а не повторно открывать таблицу:
with cte as(
select dense_rank() over (
partition by lot_id
order by try_convert(date, dateadd(second, t1.starttime, '19700101')) desc
) as seqnum
from table1 t1
)
delete from cte where seqnum > 2
Ваш запрос предполагает, что startime
это временная метка эпохи (то есть int
тип данных), поэтому другой возможной оптимизацией является использование арифметики, а не преобразование даты:
with cte as(
select dense_rank() over (
partition by lot_id
order by t1.starttime / 60 / 60 / 24 desc
) as seqnum
from table1 t1
)
delete from cte where seqnum > 2
Если ничего из этого не помогает, тогда вы можете рассмотреть возможность изменения логики: то есть перемещения записей, которые вы хотите сохранить, во временную таблицу, затем настройки и повторного заполнения исходной таблицы.
Комментарии:
1. Спасибо @GMB. Похоже, что в моем случае правильнее всего использовать обратную логику, поскольку мне нужно найти самый быстрый способ выполнить это. Вместо того, чтобы усекать, я удалил свою основную таблицу и переименовал временную таблицу с помощью cte как (select t1.*, DENSE_RANK() over (partition by Lot_ID order by TRY_CONVERT(DATE, DATEADD(second, t1.starttime, ‘19700101’) ) desc) как seqnum из Table1 t1 ) select *в Test1 из cte, где seqnum <=2; — удалить таблицу Table1; EXEC sp_rename ‘dbo.Test1’, ‘Table1’;