链接服务器性能和选项

时间:2020-03-06 14:42:41  来源:igfitidea点击:

在工作中,我们有两台服务器,其中一台正在运行许多人使用的应用程序,该应用程序具有SQL Server 2000后端。我已经可以自由查询很长时间了,但是无法向其中添加任何内容,例如存储过程或者额外的表。

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

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

另外,我目前有哪些链接服务器选项:

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

编辑:

只是以为我会更新这篇文章,我在一段时间内使用带有动态参数的openqueries来提高性能,谢谢。但是,这样做最终会使查询变得更加混乱,最终导致我们无法处理字符串。终于在今年夏天,我们将SQL Server升级到2008,并实现了实时数据镜像。老实说,开放查询正在接近我的任务的本地查询速度,但是镜像无疑使sql更易于处理。

解决方案

涉及跨链接服务器的半联接的查询往往不是很有效。使用OPENQUERY将数据填充到本地临时表中,然后从那里进行处理可能会更好。

当使用链接服务器进行这样的联接时,重要的是要使要立即连接的服务器("本地")成为拥有最多数据的服务器,而链接服务器仅提供一小部分数据,否则,是的,它将提取执行连接所需的尽可能多的数据。

替代方法包括将数据的一部分复制到临时表中,并进行大量工作以精简结果以及链接服务器可以执行的任何预处理,然后在"本地"端进行联接。

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

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

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

几年前,我在SQL 2000中编写了一个远程Linked Server应用程序,遇到了与我们描述的性能问题相同的问题。为了获得最佳性能,我最后几次重写了存储过程。

我广泛使用了临时表。我发现将大量远程数据检索到临时表中然后进行连接,操作等操作的成本较低。

展示广告执行计划和展示广告估算的执行计划往往会有所帮助,尽管我不太了解自己在看什么。

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

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

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

皇家之痛

我们以前在商店里有几台链接的服务器,事实证明它就是这样的PITA。

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

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

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

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

可以为联接使用四个部分的命名,但是更昂贵。联接可能包含可用于限制链接服务器中的数据集并使用索引列的条件。

例子:

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(或者任何链接的服务器)放在循环内!

我建议在游标循环中使用动态openqueries,而不要使用链接联接。
这是我能够复制MS Access的链接联接性能的唯一方法(至少对于单个远程表)
ms sql中的常规链接联接通过拉出大型表中的所有内容而效率太低。

-我想知道游标循环内的openqueries有什么不好?如果正确完成,则没有锁定问题。

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

解决我问题的是..

我将sql server 2000从sp2升级到了SP4,如果我们已经在sql server 2000上安装了sp4,请运行Instcat.sql。根据我的经验,如果我们对其他所有解决方法都感到精疲力尽,那么我可以向我们保证,这将肯定会起作用。

谢谢,
密塔列什
[email protected]

动态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"。而且,我可能最终会使用这种设计来只编写一个应用程序,在这种情况下,它是过度设计的。尽管如此,这意味着函数本身不必做任何花哨的工作。

无论如何,将快速的网络硬件扔给这个问题可能是更便宜的答案。