仅拥有最新数据并从表中删除其余数据的有效方法

Posted

技术标签:

【中文标题】仅拥有最新数据并从表中删除其余数据的有效方法【英文标题】:Efficient way to have only the latest data and delete the rest from a table 【发布时间】:2021-03-16 01:03:05 【问题描述】:

我正在尝试找到从表中删除数据的最快方法。我的逻辑是对于给定的 Lot_ID,Table1 中只有最近 2 天的数据,并且 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】:

您可以尝试直接从 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

如果这些都没有帮助,那么您可能需要考虑反转逻辑:即将要保留的记录移动到临时表中,然后截断并重新填充原始表。

【讨论】:

谢谢@GMB。看起来反转逻辑是我的正确方法,因为我需要看看最快的方法来执行它。我没有截断,而是删除了我的主表并将临时表重命名为 (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) select * into Test1 from cte where seqnum

以上是关于仅拥有最新数据并从表中删除其余数据的有效方法的主要内容,如果未能解决你的问题,请参考以下文章

从google bigtable中删除空行的有效方法

如何从表和所有引用中删除数据? [关闭]

从表中选择数据并从另一个表中填充特定值

从具有特定根的 SQL 表中获取最新分支的最有效方法是啥?

从表中复制数据并将其加载到另一个表中

从表视图中删除行并从 sqlite 数据库中删除记录