在视图中使用OPENQUERY对性能的影响


15

请在stackoverflow上查看此问题

我正在使用EasySoft ODBC驱动程序将SQL Server 2008 R2 Express实例链接到Interbase,并且在从远程服务器获取元数据时遇到了一些困难。从网上看,所有主要提示都使用OPENQUERY而不是链接服务器语法的四部分。

EG我目前(有问题的)方法是...

CREATE VIEW [LIVE].[vwPRDETS]
AS

SELECT *
FROM [LBLIVE]...[PRDETS] WITH (NOLOCK)

但是在某些表上,调用视图时出现错误...

消息7353,级别16,状态1,行1链接服务器“ LBLIVE”的OLE DB提供程序“ MSDASQL”提供了不一致的元数据。在执行期间提供了一个额外的列,该列在编译时找不到。

另外,我什至无法创建一些视图,因为我得到了以下...

消息7315,级别16,状态1,第1行链接服务器“ LBLIVE”的OLE DB访问接口“ MSDASQL”包含多个与名称“ SYSDBA.AUDID_LBABKP”匹配的表。

虽然只提到了一张表。

搜索网络的另一种方法似乎更像是...

SELECT *
FROM OPENQUERY(<linked sevrer>, 'SELECT <column list> FROM MyTable')

因此,我的问题是,如果我在视图定义中使用OPENQUERY,SQL Server能否优化发送到Interbase的结果SQL?还是这两种方法之间确实没有太大区别?

这是一个跨学科的话题,并且会喜欢dba的POV。

Answers:


20

摘要

让链接服务器尽可能多地执行操作。
这是不可能的SQL Server的链接服务器上优化查询,甚至另一个SQL Server

关键的因素是其中的查询运行。

在这种情况下,这是一个琐碎的SELECT,因此表中的所有行都将通过网络发送。没关系

当您添加JOIN和WHERE时,这可能很重要。您希望SQL Server允许链接服务器执行尽可能多的筛选,以减少通过网络传入的数据的大小。

例如,这里的第二种情况应该更有效。

SELECT *
FROM OPENQUERY(<linked server>, 
            'SELECT <column list> FROM MyTable') T1
     JOIN
     SomeLocalTable T2 ON ...
WHERE T1.foo = 'bar'

SELECT *
FROM OPENQUERY(<linked server>, 
           'SELECT <column list> FROM MyTable WHERE foo = ''bar''')
     JOIN
     SomeLocalTable T2 ON ...

OPENQUERY的局限性在于您无法参数化:因此您需要动态SQL来添加WHERE子句等。

链接服务器的性能可能受到的影响sp_serveroption。设置collation compatible说明了一切

如果将此选项设置为true,则SQL Server假定链接服务器中的所有字符在字符集和排序规则顺序(或排序顺序)方面均与本地服务器兼容。这使SQL Server可以将字符列上的比较发送给提供程序。如果未设置此选项,则SQL Server始终在本地评估字符列上的比较。

也就是说,请尽量不要让SQL Server在本地处理数据。

注意:在foo = 'bar'上面的第二个示例中,筛选器被发送到链接服务器,因为它只是SQL Server的字符串常量。第一个示例中的真实WHERE子句可以远程发送,也可以不远程发送。

最后,我还发现将数据分段到临时表中并将其联接到本地表上通常比直接联接到OPENQUERY更好。


+1为什么不将我的简单where子句与在远程服务器上执行的字符串文字进行比较?答案是“排序规则兼容”。谢谢。
mwardm '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.