Ant*_*nio 7 sql-server sql-server-2012
我有一个包含我的应用程序日志的表,它有 161.626.718 行(并且还在增长),并且在其上进行插入非常慢。我的想法是只保留表中 6 个月的日志和所有我想复制到应用程序无法访问的存档表上的旧记录,如果有人需要一些信息,只需直接在表上进行选择。因此,我们的想法是创建这样的日常工作:
SELECT * INTO audlog_backup FROM audlog WHERE XDATE <= DATEADD(day,-185,GETDATE())
DELETE FROM audlog WHERE XDATE <= DATEADD(day,-185,GETDATE())
Run Code Online (Sandbox Code Playgroud)
但是由于表的大小,这将花费很长时间,并且在第一次运行时会减慢甚至锁定数据库一段时间,毕竟大多数行将超过 6 个月。
第一次尽可能安全和快速地做这件事的建议是什么?
更多信息:
SQL Server 2012 标准版
创建表的脚本:
CREATE TABLE [dbo].[audlog_backup](
[PVKEY] [float] NULL,
[DKEY] [varchar](14) NULL,
[XDATE] [datetime] NULL,
[XTIME] [varchar](8) NULL,
[XFROM] [varchar](50) NULL,
[XTO] [varchar](50) NULL,
[DETAILS] [text] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
SET ANSI_PADDING ON
ALTER TABLE [dbo].[audlog_backup] ADD [XUSER] [varchar](50) NULL
ALTER TABLE [dbo].[audlog_backup] ADD [PEOPLEKEY] [int] NULL
ALTER TABLE [dbo].[audlog_backup] ADD [ADDRESSKEY] [int] NULL
ALTER TABLE [dbo].[audlog_backup] ADD [XFILEKEY] [varchar](50) NULL
ALTER TABLE [dbo].[audlog_backup] ADD [XLOGNO] [int] IDENTITY(1,1) NOT NULL
ALTER TABLE [dbo].[audlog_backup] ADD [XTABLE] [varchar](50) NULL
ALTER TABLE [dbo].[audlog_backup] ADD [XFIELD] [varchar](50) NULL
CONSTRAINT [PK_AUDLOG_backup] PRIMARY KEY NONCLUSTERED
(
[XLOGNO] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
您可以使用以下通过 SQL Server 代理作业调度的存储过程来持续存档记录。您无需担心“超过 6 个月的所有内容”的初始移动,因为此过程会自然处理它,因为它可以比您插入记录的速度更快地存档记录。当然,如果您想立即存档这些行的大部分,您可以手动运行此存储过程(当作业未运行时),只需为@BatchSize和传入稍高的参数值@SecondsToRun。
重要笔记:
@BatchSize并@SecondsToRun匹配数据进入表的速度dbo.AudLog ([XDATE] ASC)XLOGNO在主AudLog表中,从XLOGNO此处 (in AudLog_Backup)的列中删除 IDENTITY 规范,因为该值来自主AudLog表DETAILS列的数据类型更改为VARCHAR(MAX):text自 SQL Server 2005 发布以来已被弃用,并且更难使用。小注:
AudLog表空的。AudLog表上引起争用,它只会持续很短的时间。OUTPUT子句将DELETEfrom 主AudLog表绑定INSERT到AudLog_Backup事务中的表中,因此您无需担心这两个操作之间的进程失败或系统关闭/崩溃。CREATE PROCEDURE dbo.AudLog_Archive
(
@BatchSize INT = 2000, -- don't go above 3000 to avoid lock escalation
@SecondsToRun INT = 180, -- run for 3 minutes
@DaysToKeep INT = 185 -- archive rows older than 6 months
)
AS
SET NOCOUNT ON;
DECLARE @EndTime DATETIME = DATEADD(SECOND, @SecondsToRun, GETDATE()),
@ArchiveDate DATETIME = DATEADD(DAY, @DaysToKeep * -1, GETDATE()),
@RowsArchived INT = @BatchSize; -- initialize to be able to enter the loop
WHILE (@EndTime > GETDATE() AND @RowsArchived = @BatchSize)
BEGIN
IF (EXISTS(
SELECT 1
FROM dbo.AudLog al
WHERE al.[XDATE] < @ArchiveDate
)
)
BEGIN
;WITH batch AS
(
-- Keep this as SELECT * as it will alert you, via job failure, if
-- you add columns to AudLog but forget to add them to AudLog_Backup
SELECT TOP (@BatchSize) al.*
FROM dbo.AudLog al
WHERE al.[XDATE] < @ArchiveDate
ORDER BY al.[XDATE] ASC
)
DELETE b
OUTPUT DELETED.* -- keep as * for same reason as noted above
INTO dbo.AudLog_Backup ([PVKEY], [DKEY], ...) -- specify all columns
FROM batch b
SET @RowsArchived = @@ROWCOUNT;
WAITFOR DELAY '00:00:01.000'; -- one second delay for breathing room
END;
ELSE
BEGIN
BREAK;
END;
END;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13525 次 |
| 最近记录: |