SQL Server 2005从外部服务器加载数据

时间:2009-09-12 15:55:38

标签: sql sql-server sql-server-2005 tsql etl

有一个具有以下设置和要求的新项目: -

我的客户端在他们的办公室里有一台MSSQL 2005服务器(A)。他们的供应商在世界的另一个地方有一个MSSQL 2005服务器(B),它包含实时交易数据。我的客户希望在非办公时间每天从(B)到(A)加载数据。他们拥有对(B)的datareader访问权限,但就此而言,供应商不会进行复制,日志传送等,而我的客户自己负责获取自己的数据,以便他们可以运行自己的报告/多维数据集。

我使用的脚本使用分布式TSQL和链接服务器到(B): -

DECLARE @sqlCommand        VARCHAR(2000)
DECLARE @LastProcessedDate DATETIME

-- run the following code for Table 1 to Table XX

SELECT @LastProcessedDate = LastProcessedDate 
  FROM [ProcessControl] 
 WHERE TableName = 'table_1'

SET @sqlCommand = 'INSERT INTO Table1 
                   SELECT * 
                     FROM OPENQUERY(VendorsLinkedServerName, 
                          ''SELECT * 
                              FROM Table1 
                             WHERE LastModified >= '''' + @LastProcessedDate + '''')'

EXEC @sqlCommand

我对10个最大的表进行了初始试验,为期1天的数据,花了1个小时太长了。同样对于测试,我已经删除了除表的主键(包括1-4个BIGINT列)之外的所有索引和约束。关于如何加快加载时间或加载数据的任何建议?

编辑:只是添加,如果你想知道为什么select语句是这样编写的,在上面的例子中,(A)中的Table1在ETL数据库中,随后将比较数据以确定插入/更新/删除在(A)

中的实际报告数据库中

5 个答案:

答案 0 :(得分:1)

不幸的是,我认为最大的减速只是网络延迟,而且你无能为力。

但是,我确实有一个想法。尝试将ORDER BY子句添加到与目标表的主键(聚簇索引)匹配的SELECT语句中。这可以减少在插入期间重新排序表的需要。

此外,那里有多少桌子,你有多少时间?如果你已经完成了一小时内最大的10个规则,那么你可能会发现90/10规则正在发挥作用,这样所有其他表格合并的时间仍然比10个更少。

答案 1 :(得分:1)

听起来你正在寻找单向(仅下载)同步。为了获得最佳可靠性,我会要求供应商(B)添加一个ROWVERSION列,它比DateTime或DateTimeOffset更安全。

至于你的查询,我做了类似以下的事情:

INSERT INTO dbo.Table1
(
    Field1,
    Field2,
    Field3
)
SELECT
    T1.Field1,
    T1.Field2,
    T1.Field3
FROM [LinkedServer].[DatabaseName].[dbo].[Table1] T1
WHERE T1.Version > @LastAnchor

如果您的模式相同,您可以跳过整个ETL阶段,具有CreatedVersion和UpdatedVersion,如果需要,可以使用Tombstone行进行删除。 Sync Framework为您简化了很多,尽管您可以使用这些概念来相对轻松地烘焙自己的概念。规则如下:

-- get inserts in dependency order
INSERT INTO ...
SELECT ...
FROM ...
WHERE CreatedVersion > @LastAnchor
-- get updates in dependency order
UPDATE [dbo].[Table1]
SET ...
FROM [LinkedServer].[DatabaseName].[dbo].[Table1] T1
WHERE [dbo].[Table1].[PK] = T1.[PK]
    AND T1.CreatedVersion <= @LastAnchor
    AND T1.UpdatedVersion > @LastAnchor
-- get deletes (if you need them)
DELETE T
FROM [dbo].[Table1] T
JOIN [LinkedServer].[DatabaseName].[dbo].[Table1_Tombstone] T1
    ON T.[PK] = T1.[PK]
    AND T1.DeletedVersion > @LastAnchor

要使所有这些查询表现良好,应将CreatedVersion,UpdatedVersion和DeletedVersion列编入索引。

以上所有逻辑都适用于DateTime或RowVersion,只是RowVersion更准确,并且2005 SP2解决了正在进行的事务中的一些问题。基本上在SQL 2005 SP2和SQL 2008中,您将最大锚设置为MIN_ ACTIVE_ROWVERSION() - 1并查询其间的内容。查看MSDN notes以获取有关原因的更多信息。

与某些人不同,我强烈建议不要将UpdatedVersion作为聚集索引,因为这将涉及在完成更新时对页面上的数据进行不断的重新排序,如果您向供应商推荐,您将看起来像个傻瓜。

使用Sync Framework的一个优点是,您可以使用WCF进行数据调用,并在每天结束时定期执行较小的同步,而不是大规模的同步。这将要求供应商提供或至少托管提供数据库访问的WCF服务。如果您愿意,仍然可以使用带有Sync Framework的链接服务器,同时仍然支持更频繁地执行较小的同步。

答案 2 :(得分:0)

性能是由于网络延迟而不是您采用的方法吗?你在处理什么样的卷等。

我注意到他们不会进行复制或日志传送,但您是否可以与他们讨论做一些预定的批量导出,这些导出可以压缩并发送到另一端的自动例程进行批量插入?

答案 3 :(得分:0)

在本地尝试查询(或尝试让它们在本地运行查询)并查看需要多长时间。正如克里斯所说,这可能是网络延迟。您是否有能力在供应商方面推出SSIS包?如果是这样,您可以提取和压缩数据,通过FTP任务或其他机制将其发送出去,然后解压缩/插入数据。

答案 4 :(得分:0)

你可能想做一些测试来确定减速的位置,正如Chris W所暗示的那样。

例如,执行查询并将信息转储到文件中,然后计时。

运行查询的时间,并忽略您获得的任何数据,以查看传输数据所需的时间。

然后你知道转移的时间以及如果你把你的数据库带出循环会发生什么。

然后,您可以确定最佳行动方案。

您可能还想进行大量的个人查询。

所以,花时间从一张大桌子转移需要多长时间。

然后对大表进行5次查询,看看会发生什么。

如果可能的话,您可能想要查看是否可以同时建立多个连接,并快速d / l数据,将其转储到空数据库中,然后通过从本地副本复制到数据库来为索引付出代价。 / p>

但是,所有这些都是毫无意义的,直到你有一些数字来看看这些操作需要多长时间。