ビューでOPENQUERYを使用することのパフォーマンスへの影響


15

stackoverflowでこの質問を参照してください。

EasySoft ODBCドライバーを使用して、SQL Server 2008 R2 ExpressインスタンスをInterbaseにリンクしていますが、リモートサーバーからメタデータを取得するのに多少苦労しています。ネット上で見ると、主な提案はすべて、4つの部分のリンクサーバー構文の代わりに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 "。" AUDIT_LBABKP ""に一致する複数のテーブルが含まれています。

ただし、言及されている表は1つだけです。

ネットを検索する別の方法は、もっと似ているようです...

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

したがって、私の質問は、ビュー定義でOPENQUERYを使用すると、SQL ServerはInterbaseに送信される結果のSQLを最適化できますか?それとも、2つのアプローチの間にそれほど大きな違いはありませんか?

それはクロスオーバーの主題であり、dbaのPOVが大好きです。

回答:


20

概要

リンクサーバーにできる限りのことをさせます。SQL Serverがリンクサーバー、さらには別のSQL Serverでクエリを最適化する
ことは不可能です

長いです

重要な要因であるところ、クエリが実行されます。

この場合、これは単純なSELECTであるため、テーブルのすべての行が送信されます。関係ありません。

JOINとWHEREを追加するとき、それは重要です。ネットワーク経由で送信されるデータのサイズを削減するために、SQL Serverでリンクサーバーができるだけ多くのフィルタリングを実行できるようにする必要があります。

たとえば、ここの2番目のケースはより効率的です。

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の制限は、パラメーター化できないことです。したがって、WHERE句などを追加するには動的SQLが必要です。

リンクサーバーのパフォーマンスはの影響を受ける可能性がありますsp_serveroption。設定collation compatibleはそれをすべて言います

このオプションがtrueに設定されている場合、SQL Serverは、文字セットと照合順序(または並べ替え順序)に関して、リンクサーバー内のすべての文字がローカルサーバーと互換性があると想定します。これにより、SQL Serverは文字列の比較をプロバイダーに送信できます。このオプションが設定されていない場合、SQL Serverは常に文字列の比較をローカルで評価します。

つまり、SQL Serverがデータをローカルで処理しないようにしてください。

注:foo = 'bar'上記の2番目の例では、フィルターはSQL Serverへの単なる文字列定数であるため、リンクサーバーに送信されます。最初の例の実際のWHERE句は、リモートで送信される場合とされない場合があります。

最後に、データを一時テーブルにステージングしてローカルテーブルに結合する方が、OPENQUERYに直接結合するよりも優れている場合が多いこともわかりました。


+1リモートサーバーで実行されている文字列リテラルに対する単純なwhere句の比較が行われなかったのはなぜですか?答えは「照合互換」でした。ありがとう。
mwardm
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.