每晚我都需要修剪一张表,只包含最新的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()以某种方式来做它?订购它们并删除所有ROW_NUMBER大于20,000的东西?但我无法让它发挥作用。子查询是我最好的选择还是有更好的方法?
答案 0 :(得分:7)
如果似乎效率低下,我会确保在开始咆哮错误的树之前效率低下。
测量时间,CPU使用率,磁盘I / O等,以了解它的执行情况。我想你会发现它的表现比你想象的要好。
答案 1 :(得分:3)
当然,你的里程会有所不同 - 这将取决于你从这张桌子的底部刮下多少真实记录,但这里有另一种选择。
备注:由于您有一个“Date_Added”字段,是否值得考虑简单地保留上次运行的日期时间并在where子句中使用它来过滤要删除的记录?现在,不是20,000条记录,而是在日志中允许X天......只是想一想......
- 获取我们想要保持的温度记录
- 您可以根据需要对饲养员进行分类。
select top 20000 * into #myTempTable from MyTable ORDER BY DateAdded DESC
- 使用truncate不会废弃我们的日志文件并使用更少的sys资源...
truncate table MyTable
- 将我们的“保留”记录带回到折叠中......
- 这假设您没有使用标识栏 - 如果您使用,则应该使用
- 指定字段名称而不是使用'*',并执行类似
的操作
- SET IDENTITY_INSERT MyTable ON
- 从#myTempTable中插入MyTable select field1,field2,field3
- (我认为是对的)
insert into MyTable select * from #myTempTable
- 做一个好公民。
drop table #myTempTable
希望有所帮助 -
答案 2 :(得分:3)
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 :(得分:1)
将20000插入临时表,然后从主表中删除所有记录,然后再次插入 从临时表到主表的20000条记录..,
答案 4 :(得分:0)
当然,这是包装到程序并使用两个sql语句的首要案例 - 第一个选择最新的ID并减去20,000,然后第二个删除ID低于此的所有行。
然而,从表面上来看,这听起来好像你最终将会采用这种方法进行大量碎片化,这可能是创建新表,插入最新20,000条记录的好参数,删除旧的并重命名新的。甚至可能值得将表放在不同的数据库中并从主数据库创建视图以方便访问。我自己通常倾向于使用用于数据加载和审计的表格。
在不知道您的实际数据量和行为的情况下很难判断,但很可能全球范围内的效率低于您使用的删除方法。如果你每天只收集一千个或更少的记录,那么删除可能与运行数据优化维护计划相结合,但更多,我会考虑更激烈的方法。
答案 5 :(得分:0)
你的问题意味着你正在修剪以从表中获得更好的白天表现。您是否在日间查询中获得表扫描?不是更好的指数是答案吗?或者你是否陷入了“糟糕的架构”?
或者确实有一些非常奇怪的情况,你确实需要清除旧记录? 20,000是一个难又快的数字?或者日期时间可以工作吗?然后,日期时间列上的索引将使修剪更容易。