「ドット」表記を使用した最初の例では、クライアント カーソル エンジンが使用され、ほとんどのものがローカルで評価されます。大きなテーブルから選択して WHERE 句を使用している場合、レコードはリモート データベースからローカルに取得されます。リンク サーバーを介してデータが取得されると、WHERE 句がローカルに適用されます。多くの場合、このシーケンスはパフォーマンス ヒットです。リモート データベースのインデックスは、基本的に役に立たなくなります。
または、OPENQUERY を使用すると、SQL Server は sql ステートメントをターゲット データベースに送信して処理します。処理中に、テーブルのインデックスが活用されます。また、結果セットを SQL Server に送り返す前に、where 句が Oracle 側に適用されます。
私の経験では、最も単純なクエリを除いて、OPENQUERY を使用するとパフォーマンスが向上します。
上記の理由から、すべてに OpenQuery を使用することをお勧めします。
すでに遭遇しているかもしれない OpenQuery を使用する際の問題点の 1 つは、一重引用符です。リモート データベースに送信される SQL 文字列で、文字列または日付を単一引用符で囲む必要がある場合は、エスケープする必要があります。そうしないと、誤って SQL 文字列を終了してしまいます。
以下は、リンク サーバーへの openquery ステートメントで変数を処理するときに、単一引用符の問題を処理するために使用するテンプレートです。
DECLARE @UniqueId int
, @sql varchar(500)
, @linkedserver varchar(30)
, @statement varchar(600)
SET @UniqueId = 2
SET @linkedserver = 'LINKSERV'
SET @sql = 'SELECT DummyFunction(''''' + CAST(@UniqueId AS VARCHAR(10))+ ''''') FROM DUAL'
SET @statement = 'SELECT * FROM OPENQUERY(' + @linkedserver + ', '
SET @Statement = @Statement + '''' + @SQL + ''')'
EXEC(@Statement)