Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server 2005正在从外部服务器加载数据_Sql_Sql Server_Sql Server 2005_Tsql_Etl - Fatal编程技术网

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

SQL Server 2005正在从外部服务器加载数据,sql,sql-server,sql-server-2005,tsql,etl,Sql,Sql Server,Sql Server 2005,Tsql,Etl,拥有具有以下设置和要求的新项目:- 我的客户在他们的办公室里有一台MSSQL 2005服务器(a)。他们的供应商在世界的另一个地方有一台MSSQL 2005服务器(B),其中包含实时事务数据。我的客户希望在非办公时间每天将数据从(B)加载到(A)。他们可以使用datareader访问(B),但也就是说,供应商不会进行复制、日志传送等,我的客户全权负责获取他们自己的数据,以便他们可以运行自己的报告/多维数据集 我使用的脚本如下所示,使用分布式TSQL并将服务器链接到(B):- 我对10个最大的表进

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

我的客户在他们的办公室里有一台MSSQL 2005服务器(a)。他们的供应商在世界的另一个地方有一台MSSQL 2005服务器(B),其中包含实时事务数据。我的客户希望在非办公时间每天将数据从(B)加载到(A)。他们可以使用datareader访问(B),但也就是说,供应商不会进行复制、日志传送等,我的客户全权负责获取他们自己的数据,以便他们可以运行自己的报告/多维数据集

我使用的脚本如下所示,使用分布式TSQL并将服务器链接到(B):-

我对10个最大的表进行了一整天的初步试验,结果花了1个小时,时间太长了。同样在测试中,我已经删除了表的所有索引和约束,除了主键(包含1-4个BIGINT列)。关于如何加快加载时间或着手加载数据,有什么建议吗


编辑:只是为了添加,如果您想知道select语句为何以这种方式编写,在上面的示例中,(A)中的表1位于ETL数据库中,随后将比较数据以确定(A)中实际报告数据库中的insert/update/delete

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


我注意到他们不会进行复制或日志传送,但您能否说服他们进行一些计划的批量导出,这些导出可以被压缩并发送给另一端的自动化例程以进行批量插入?

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

正如Chris W所建议的,您可能需要进行一些测试以确定减速的位置

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

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

然后您就知道了传输的时间,以及如果将数据库从循环中取出会发生什么

然后你可以决定最佳的行动方案

您可能还需要执行许多单独的查询

那么,从一张大桌子转移到另一张桌子需要多长时间

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

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


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

不幸的是,我猜最大的减速只是网络延迟,对此你无能为力

不过,我有一个想法。尝试将ORDERBY子句添加到与目标表的主键(聚集索引)匹配的SELECT语句中。这样可以减少在插入过程中对表格重新排序的需要


还有,有多少张桌子,你有多少时间?如果你在一个小时内完成了最大的10张桌子,你可能会发现有一个90/10的规则在起作用,所有其他桌子加起来所花的时间仍然比那10张桌子少

听起来您在寻找单向(仅下载)同步。为了获得最佳可靠性,我会要求供应商(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,并在需要时使用墓碑行进行删除。为您简化了很多,尽管您可以使用这些概念相对轻松地烘焙自己的产品。规则如下:

-- 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>@LastAnchor
--按依赖关系顺序获取更新
更新[dbo]。[表1]
设置
来自[LinkedServer].[DatabaseName].[dbo].[Table1]T1
其中[dbo].[Table1].[PK]=T1.[PK]
和T1.CreatedVersion@LastAnchor
--获取删除(如果需要)
删除T
来自[dbo].[Table1]T
加入[LinkedServer].[DatabaseName].[dbo].[Table1\u Tombstone]T1
在T[PK]=T1[PK]上
和T1.DeletedVersion>@LastAnchor
为了使所有这些查询都能很好地执行,应该对CreatedVersion、UpdatedVersion和DeletedVersion列进行索引

以上所有逻辑都适用于DateTime或RowVersion,只是RowVersion更准确,而且2005SP2解决了一些关于进行中事务的问题。基本上,在SQL 2005 SP2和SQL 2008中,您将max ANCHORK设置为MIN_uactive_ROWVERSION()-1,并查询介于两者之间的内容。有关原因的更多信息,请查阅

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


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

这是一个建议,因此我将此作为一个注释:您是否尝试过SQL数据比较?()换乘时间可以接受多久?没有人能帮你
-- 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