我有一个非常大的数据库(~100Gb),主要由两个我想要减小大小的表组成(两个表都有大约 5000 万条记录)。我在同一台服务器上设置了一个存档数据库,其中包含这两个表,使用相同的架构。我正在尝试确定从实时数据库中删除行并将其插入存档数据库中的最佳概念方法。在伪代码中,这就是我现在正在做的事情:
Declare @NextIDs Table(UniqueID)
Declare @twoYearsAgo = two years from today's date
Insert into @NextIDs
SELECT top 100 from myLargeTable Where myLargeTable.actionDate < twoYearsAgo
Insert into myArchiveTable
<fields>
SELECT <fields>
FROM myLargeTable INNER JOIN @NextIDs on myLargeTable.UniqueID = @NextIDs.UniqueID
DELETE MyLargeTable
FROM MyLargeTable INNER JOIN @NextIDs on myLargeTable.UniqueID = @NextIDs.UniqueID
现在需要 7 分钟才能完成 1000 条记录,速度慢得可怕。我测试了删除和插入,两者都花费了大约。 3.5 分钟即可完成,因此其中一个不一定比另一个效率低得多。谁能指出一些优化思路?
谢谢!
这是 SQL Server 2000。
编辑:在大型表上,ActionDate 字段上有一个聚集索引。还有其他两个索引,但在任何查询中都没有引用。 Archive 表没有索引。在我的测试服务器上,这是唯一命中 SQL Server 的查询,因此它应该具有足够的处理能力。
代码(一次循环处理 1000 条记录):
DECLARE @NextIDs TABLE(UniqueID int primary key)
DECLARE @TwoYearsAgo datetime
SELECT @TwoYearsAgo = DATEADD(d, (-2 * 365), GetDate())
WHILE EXISTS(SELECT TOP 1 UserName FROM [ISAdminDB].[dbo].[UserUnitAudit] WHERE [ActionDateTime] < @TwoYearsAgo)
BEGIN
BEGIN TRAN
--get all records to be archived
INSERT INTO @NextIDs(UniqueID)
SELECT TOP 1000 UniqueID FROM [ISAdminDB].[dbo].[UserUnitAudit] WHERE [UserUnitAudit].[ActionDateTime] < @TwoYearsAgo
--insert into archive table
INSERT INTO [ISArchive].[dbo].[userunitaudit]
(<Fields>)
SELECT <Fields>
FROM [ISAdminDB].[dbo].[UserUnitAudit] AS a
INNER JOIN @NextIDs AS b ON a.UniqueID = b.UniqueID
--remove from Admin DB
DELETE [ISAdminDB].[dbo].[UserUnitAudit]
FROM [ISAdminDB].[dbo].[UserUnitAudit] AS a
INNER JOIN @NextIDs AS b ON a.UniqueID = b.UniqueID
DELETE FROM @NextIDs
COMMIT
END
最佳答案
在执行插入/删除命令之前,您实际上需要运行三个选择:
对于第一个插入:
SELECT top 100 from myLargeTable Where myLargeTable.actionDate < twoYearsAgo
第二次插入:
SELECT <fields> FROM myLargeTable INNER JOIN NextIDs
on myLargeTable.UniqueID = NextIDs.UniqueID
删除:
(select *)
FROM MyLargeTable INNER JOIN NextIDs on myLargeTable.UniqueID = NextIDs.UniqueID
我会尝试优化这些,如果它们都很快,那么索引可能会减慢您的写入速度。一些建议:
启动分析器并查看读/写等情况。
检查所有三个语句的索引使用情况。
尝试运行仅返回 PK 的
SELECT
,以查看延迟是否是查询执行或获取数据(例如是否有任何全文索引字段、TEXT
字段等)
关于sql - SQL 归档存储过程的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1876472/