1

我有一个 Web 应用程序,它从包含消息跟踪日志的 SQL 数据库中读取数据,出于性能原因,我想确保数据库中的日志不会超过 2 天。

通常这是一个简单的挑战,只需使用删除语句删除记录即可?

不幸的是,对我来说不是那么简单,该表包含数百万的记录计数,并且删除语句需要一段时间才能运行。有没有办法让这个更快?

我目前正在这样做:

DECLARE @CutOffDate datetime;
SET @CutOffDate = DATEADD(d, -2, GETDATE());

WHILE @@ROWCOUNT > 0
BEGIN
    DELETE TOP (2000) E12_MessageTracking
    WHERE [TimeStamp] < @CutOffDate;

    DELETE TOP (2000) E12_MessageTracking_Recipients
    WHERE [TimeStamp] < @CutOffDate;
END

我非常频繁地运行批量插入查询,因此我也需要能够频繁地运行删除,但目前该任务在删除语句上“超限”并且运行的脚本无法跟上实时。

更新:

这是你们要求的版本信息:

Microsoft SQL Server 2008 R2 (RTM) - 10.50.1810.0 (X64) Feb 3 2012 17:19:10 版权所有 (c) Microsoft Corporation Standard Edition (64-bit) o​​n Windows NT 6.1 (Build 7600:) (Hypervisor)

对于索引,表没有 PK/FK 关系,但它们“链接”在名为 MessageID 的字段上。问题是 MessageID 并不总是填写,所以我使用了一个名为 InternalMessageID 的子字段,它可以更好地链接。我遇到的问题之一是 E12_MessageTracking 表中的每条消息都有多行,它们链接到 E12_MessageTracking_Recipients 表。

我很想在这些表之间建立适当的关系,但现在我不能,因为如果不使用预先存在的 InternalMessageID 或 MessageID 列,我无法识别与消息相关的所有项目。

对于索引,它们如下所示:

E12_MessageTracking

InternalMessageID 列的索引,包括为时间戳和事件设置的列

E12_MessageTracking_Recipients

InternalMessageID 列的索引,包括为时间戳和收件人设置的列

谢谢,克里斯。

4

1 回答 1

1

我要考虑的第一件事是确保表有一个索引,TimeStamp第一个索引列在哪里。

更多详情:

如果 Timestamp 不是第一列,并且您的查询没有过滤它之前的列,则无法使用索引(想象一下在您知道第二个第一个字母的图书馆中寻找一本书单词)。

通过查看 SSMS 中脚本的执行计划,您可以有一个更好的想法。如果查询上E12_MessageTracking说 a Table Scan,那么没有使用索引。

于 2012-06-25T09:18:16.153 回答