首页 > 代码库 > SQL Sever--Linked Servers

SQL Sever--Linked Servers

当使用链接服务器(Linked Servers)时,最昂贵的代价就是网络带宽间大量数据的传输。在正确的服务器书写正确的代码是非常重要的,因为每一个错误都会导致在网络带宽上付出非常昂贵的代价。 下面是使用链接服务器(Linked Servers)时的几个常见错误:

1:使用推送方式而不是拉方式取数

   出人意料之外的是,使用链接服务器推送数据比拉取数据慢得多。Linchi Shea写了一篇很好的博客讨论这个。

   Linchi Shea 使用openquery来说明两者间的差异,但是这个也会发生在使用链接服务器的SQL语句中(这里不好翻译,其实就是查询中使用Linked Server需要用到 LinkServer.DatabaseName.dbo.TableName)

2: 使用JOIN

    跨服务器查询时,为了在两台服务器之间的数据集之间执行JOIN操作,SQL Server需要将数据从一台服务器传送到另外一台服务器。如果传送的数据是一个非常大的表,这个过程可能会非常痛苦。通常来说,数据会从远程服务器传送到本地服务器。为了防止大量数据在服务器之间大传送,你可以通过在查询条件中过滤数据,通过一个远程存储过程只取回相关数据来达到目的,万一你需要使用INNER JOIN关联两个不同服务器之间的数据集,而且本地表的数据量远小于远程服务器的那个表。你可以使用REMOTE JOIN HINT, 这样就会将数据从本地服务器将数据传送到远程服务器,从而提高性能

3:使用UNION

    正如JOIN操作,UNIION不同服务器之间的两个数据集必定导致从远程服务器传送数据到本地服务器。即使你执行远程查询合并(UNION)同一个远程服务器的两个数据集,还是会先将两个数据集传送到本地服务器,然后UNION两个数据集,可以通过远程存储过程,函数或视图先UNION数据库来阻止这个

4:书写太复杂的查询语句

  优化器不能总是能明白你需要做什么,尤其是你的SQL语句中使用了链接服务器(Linked Server)时,例如, 我遇到过一个类似如下SQL语句,执行了10分钟

   1: SELECT *
   2: FROM LocalTable
   3: WHERE SomeColumn <
   4: (SELECT COUNT(*)
   5:  FROM RemoteServer.SomeDB.dbo.SomeTable
   6:  WHERE SomeColumn > 100)

我像这样修改了查询语句

   1: DECLARE @Count INT
   2: SELECT @Count = COUNT(*)
   3: FROM RemoteServer.SomeDB.dbo.SomeTable
   4: WHERE SomeColumn > 100
   5:  
   6: SELECT *
   7: FROM LocalTable
   8: WHERE SomeColumn < @Count

 

这样重写SQL后,查询语句只跑了一秒就查询出结果了,保持SQL脚本简单。


5:当数据库位于同一个实例时使用链接服务器(Linked Server)
  

这种场景的性能损耗可能不像其它场景那样明显,但是这种方式比使用数据库前缀(Database.dbo.TableName)要慢

如果你想区别这两种情形,可以在测试数据库测试、对比这两种方法的性能,然后决定性能的提升是否值得在生产环境修改代码。在某些情况下,它是会提升性能的。

 

 

主要问题:1、性能问题  2、安全问题

SQL Sever--Linked Servers