9

在工作中,我们有两台服务器,一台正在运行一个很多人使用的应用程序,它有一个 SQL Server 2000 后端。很长一段时间以来我一直可以自由地查询它,但不能向它添加任何东西,例如存储过程或额外的表。

这导致我们将第二个 SQL Server 链接到第一个 SQL Server,而我构建了一个存储过程库,该库使用链接服务器从双方查询数据。其中一些查询花费的时间比我想要的要长。

有人可以给我一些关于使用链接服务器的好文章吗?我对找出两者之间正在传输的数据特别感兴趣,因为通常大多数 sql 语句都可以远程执行,但我感觉它可能正在传输完整的表,它通常只是一个小的 final 的连接本地表。

另外我目前有什么链接服务器选项:

  • 校对兼容 True
  • 数据访问真
  • RPC 真
  • Rpc 输出真
  • 使用远程整理 False
  • 排序规则名称(空白)
  • 连接超时 0
  • 查询超时 0

编辑:

只是想我会更新这篇文章,我使用了带有动态参数的 openqueries 一段时间来提高性能,谢谢你的提示。但是,当您最终处理字符串时,这样做会使查询更加混乱。终于在今年夏天,我们将 SQL Server 升级到 2008 并实现了实时数据镜像。老实说,对于我的任务,开放查询的速度已经接近本地查询的速度,但镜像确实使 sql 更容易处理。

4

9 回答 9

8

避免连接到链接的服务器表。

可以为您的连接使用四部分命名,但成本更高。您的联接可能包含可用于限制来自链接服务器的数据集并使用索引列的条件。

例子:

SELECT loc.field1, lnk.field1
FROM MyTable loc
INNER JOIN RemoteServer.Database.Schema.SomeTable lnk
  ON loc.id = lnk.id
  AND lnk.RecordDate = GETDATE()
WHERE loc.SalesDate = GETDATE()

此查询还在连接中应用一个条件,链接服务器可以在计算连接之前使用该条件。

推荐的方法是使用 OPENQUERY。

通过使用 OPENQUERY 避免连接,本地服务器只发送要远程执行的查询,而不是发送一组用于连接的 ID。

使用该链接检索一组数据并在本地执行计算。要么使用临时表(用于临时查询),要么在夜间作业中将行插入到永久表中。

如果在喜欢的服务器中设置了远程事务协调器,开始事务可能会失败。使用它会消耗更多的资源。

还要考虑到您正在访问运行应用程序的生产服务器,虽然您没有指定它,但我认为可以安全地假设它正在使用大量事务并进行插入和更新。您正在从应用程序中夺走资源。

您的目的似乎是将数据用于报告目的。您的服务器可以设置为具有简单日志而不是完整日志,从而提高效率。

您还将避免由于链接服务器上的数据移动而取消您的查询。始终注意为查询和表提示(如 NOLOCK)设置适当的隔离级别。

请!切勿将 OPENQUERY(或任何链接服务器)放在循环中!

于 2008-09-27T05:53:25.940 回答
3

当您使用链接服务器进行此类连接时,重要的是让您立即连接到的服务器(“本地”)成为拥有最多数据的服务器,其中链接服务器仅提供一小部分数据,否则,是的,它将提取执行连接所需的尽可能多的数据。

替代方法包括将数据的子集复制到临时表中,并完成尽可能多的工作以缩小结果和链接服务器可以执行的任何预处理,然后在“本地”端进行连接。

您可能会发现,您可以通过反转操作方式轻松提高性能,连接到您无法控制的服务器(他们需要为您创建链接服务器),然后通过链接连接到您的服务器。如果您需要对必须创建存储过程的数据进行主要工作 - 然后将数据推送到您的服务器并在那里使用您的存储过程。

在某些情况下,我只是让链接服务器每晚创建这种摘要,然后将其推送到本地服务器,然后本地服务器通过连接执行其工作。

于 2008-09-25T14:02:54.840 回答
3

皇家之痛

我们曾经在我们的商店有几个链接服务器,结果就是这样一个 PITA

首先,存在与您描述的类似的严重性能问题。当我看到网络 I/O 统计信息时,我感到很震惊。尽管付出了所有努力,但我们未能提示 SQL Server 采取合理的行为。

另一个问题是存储过程将这些链接的服务器名称硬编码在任何地方,无法覆盖它们。因此,开发人员无法在他们的开发沙箱上轻松测试任何涉及链接服务器的功能。这是创建通用单元测试套件的主要障碍。

最后,我们完全放弃了链接服务器,并将数据同步转移到了 Web 服务。

于 2008-09-26T23:19:27.043 回答
2

涉及跨链接服务器的半连接的查询往往效率不高。您最好使用OPENQUERY将数据填充到本地临时表中,然后从那里处理它。

于 2008-09-25T09:30:23.793 回答
1

几年前,我在 SQL 2000 中编写了一个远程链接服务器应用程序,并遇到了与您描述的相同的性能问题。为了获得最佳性能,我最终多次重写了我的存储过程。

我广泛使用临时表。我发现将大量远程数据检索到临时表中,然后加入它、操作它等成本更低。正如您所描述的那样,将本地连接到远程表非常慢。

Display Execution Plan 和 Display Estimated Execution Plan 往往会有所帮助,尽管我看不懂很多东西。

我不知道是否真的有一种有效的方法可以使用远程服务器执行这些查询,因为 SQL Server 在针对链接服务器时似乎无法利用其正常优化。您可能会觉得您正在转移整个表格,因为事实上这就是正在发生的事情。

我想知道复制方案是否适合您。通过在本地服务器上保存数据,您应该能够编写将按需要执行的正常查询。

我不知道有什么好文章可以指点你。当我编写更复杂的 SQL Server 应用程序时,我开始认为我需要更好地了解 SQL Server 在底层是如何工作的。为此,我们购买了由 Kalen Delaney 编辑的 MS Press Inside Microsoft SQL Server 2005 系列。第 1 卷:存储引擎绝对是开始的地方,但我还没有深入了解它。由于我最近的几个项目没有涉及 SQL Server,因此我对它的研究变得松懈。

于 2008-09-26T21:38:19.580 回答
0

您是否有可能在服务器上设置单独的数据库而不是使用链接服务器?

于 2008-09-25T15:29:43.680 回答
0

我建议在游标循环中使用动态开放查询,而不是链接连接。这是我能够复制 MS Access 的链接联接性能(至少对于单个远程表)的唯一方法

,ms sql 中的常规链接联接效率太低,因为它专门在巨大的表中提取所有内容。

-- 我想知道游标循环中的开放查询有什么不好?如果操作正确,则不会出现锁定问题。

于 2008-09-30T15:04:14.983 回答
0

这是一个非常慷慨的问题,可能有很多解决方案。但正如我们目睹的许多用户说他们已经尝试了一切。

解决我的问题的是..

我将 sql server 2000 从 sp2 升级到 SP4,如果您已经在 sql server 2000 上安装了 sp4,则运行 Instcat.sql。根据我的经验,我可以向您保证,如果您对所有其他解决方法感到筋疲力尽,这肯定会奏效。

谢谢, Mithalesh mithalesh.gupta@gmail.com

于 2009-07-20T07:10:44.887 回答
0

动态 SQL 和函数可用于绕过硬编码名称问题。例如,我正在尝试一个实现,其中输入'cpi.cpi'(目的CPI,子目的默认)的函数ufn_linkedDatabase(@ purpose nvarchar(255))返回'[SERVER-NAME.DOMAIN.LCL,2000]。 [CPI]' 在生产环境中(我们使用 SQL Server 的备用端口号,我不知道为什么,包括链接服务器名称)。然后在@template varchar(max) 中组装一条SQL 命令,表达式@{cpi.cpi} 表示链接的服务器和数据库,然后@workstring = REPLACE(@template, N'@{cpi.cpi}', 。 ..) . 函数实际获取数据库名称的方式与过程是分开的——查找表很好。

问题 - 执行 OPENQUERY(),至少除非链接服务器选项“排序规则兼容”设置为“true”,否则可能会更好,以便可以在链接服务器上执行更多任务 - 即使在快速网络上也很重要,而且我们的服务器机房内部网络速度相当快 - 要执行 OPENQUERY(),我可能需要分别处理 'cpi.cpi.server' 和 'cpi.cpi.database' 和 'cpi.cpi.server.database'。而且,我最终可能会使用这种设计编写一个应用程序,在这种情况下,它是过度设计的。尽管如此,这意味着函数本身不必是任何花哨的工作。

无论如何,在问题上投入快速网络硬件可能是更便宜的答案。

于 2009-08-03T15:30:16.267 回答