归档过程运行速度不够快

Mar*_*art 2 performance sql-server execution-plan query-performance

我正在将数据从一个数据库归档到另一台 SQL 服务器上的另一个数据库。我们正在我们的数据库中归档多个表。最近我们对源数据库的插入增加了,但归档运行速度不够快。我正在考虑将表的归档拆分为单独的作业,但是我可以做些什么来提高查询的性能。

这是估计的执行计划

这是实际的执行计划

实际计划中的 QueryTimeStats 如下

+-----------+---------+-------------+---------+
| Statement | CpuTime | ElapsedTime | Percent |
+-----------+---------+-------------+---------+
|         1 |       3 |           3 | 0.00%   |
|         2 |       3 |           4 | 0.00%   |
|         3 |       0 |           0 | 0.00%   |
|         4 |       1 |           1 | 0.00%   |
|         5 |       0 |           1 | 0.00%   |
|         6 |       1 |           1 | 0.00%   |
|         7 |       6 |           6 | 0.01%   |
|         8 |       0 |           1 | 0.00%   |
|         9 |     516 |         538 | 0.49%   |
|        10 |   76063 |       79110 | 71.84%  |
|        11 |     496 |       21621 | 19.63%  |
|        12 |      91 |         237 | 0.22%   |
|        13 |       4 |           4 | 0.00%   |
|        14 |       3 |           4 | 0.00%   |
|        15 |    2176 |        2446 | 2.22%   |
|        16 |    2581 |        5102 | 4.63%   |
|        17 |      92 |         293 | 0.27%   |
|        18 |      20 |          39 | 0.04%   |
|        19 |       2 |           2 | 0.00%   |
|        20 |       3 |         242 | 0.22%   |
|        21 |       0 |           0 | 0.00%   |
|        22 |       0 |           0 | 0.00%   |
|        23 |       2 |           2 | 0.00%   |
|        24 |       5 |           6 | 0.01%   |
|        25 |     139 |         139 | 0.13%   |
|        26 |       0 |           1 | 0.00%   |
|        27 |       4 |           3 | 0.00%   |
|        28 |       4 |           6 | 0.01%   |
|        29 |      77 |          77 | 0.07%   |
|        30 |       0 |           1 | 0.00%   |
|        31 |       9 |           8 | 0.01%   |
|        32 |       3 |           4 | 0.00%   |
|        33 |       0 |           0 | 0.00%   |
|        34 |       1 |           1 | 0.00%   |
|        35 |       4 |           4 | 0.00%   |
|        36 |       5 |           8 | 0.01%   |
|        37 |      81 |          82 | 0.07%   |
|        38 |       0 |           1 | 0.00%   |
|        39 |       3 |           3 | 0.00%   |
|        40 |       4 |           6 | 0.01%   |
|        41 |     105 |         105 | 0.10%   |
|        42 |       1 |           7 | 0.01%   |
+-----------+---------+-------------+---------+
Run Code Online (Sandbox Code Playgroud)

Han*_*non 5

通过链接服务器从源端进行插入会影响性能。插入到目标中的每一行都是通过游标操作内的离散 INSERT 语句插入的。即,如果您向目标中插入 12,000 行,SQL Server 实际上将执行插入 12,000 次,每行一次。

如果你因此它从运行重新写入归档进程的目标服务器,这将是快。

作为执行计划中的一个示例,请重写以下内容:

INSERT INTO @MessageEvent (ID, DateTime) 
SELECT TOP (1500) ID, TimeStamp 
FROM ConnectAPI.dbo.MessageEvent (NOLOCK) 
ORDER BY ID
Run Code Online (Sandbox Code Playgroud)

并从目标服务器运行它,如下所示:

INSERT INTO ConnectAPI.dbo.MessageEvent (ID, DateTime)
SELECT TOP(1500) ID, TimeStamp
FROM [SourceServer].ConnectAPI.dbo.MessageEvent
ORDER BY ID
Run Code Online (Sandbox Code Playgroud)

请注意,我遗漏了NOLOCK查询提示。您可能希望确保了解READ UNCOMMITTED 隔离下部分读取和/或重复读取的含义,这是与NOLOCK提示一起使用的隔离级别。

我在SQLServerScience.com上写了一篇博客文章,其中包含最少完整、可验证的示例代码,展示了从源服务器到目标服务器的 800,000 行简单插入如何在从源服务器执行时花费 7 多分钟,而从源服务器执行时仅花费 11 秒目的地。