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

Ric*_*ews 15 sql-server-2008

请在 stackoverflow 上查看此问题

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

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

CREATE VIEW [LIVE].[vwPRDETS]
AS

SELECT *
FROM [LBLIVE]...[PRDETS] WITH (NOLOCK)
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

虽然只提到了其中一张表。

搜索网络的替代方法似乎更像是......

SELECT *
FROM OPENQUERY(<linked sevrer>, 'SELECT <column list> FROM MyTable')
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是,如果我在视图定义中使用 OPENQUERY,SQL Server 是否能够优化发送到 Interbase 的结果 SQL?或者这两种方法之间真的没有太大区别?

这是一个交叉主题,会喜欢 dba 的 POV。

gbn*_*gbn 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 ...
Run Code Online (Sandbox Code Playgroud)

OPENQUERY 的一个限制是你不能参数化:所以你需要动态 SQL 来添加 WHERE 子句等。

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

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

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

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

最后,我还发现将数据暂存到临时表并将其连接到本地表通常比直接连接到 OPENQUERY 更好。