トレースフラグ7300をオンにすると、より詳細なエラーメッセージが表示される可能性があります
代表的なクエリは何行を返しますか?2つのサーバー間のネットワーク接続の速度/信頼性はどのくらいですか?
大規模なデータセットの転送に時間がかかりすぎる可能性があります(実際のクエリ時間に加えて)。タイムアウト値を上げることができます。
次のようにして、タイムアウト設定の再構成を試みることができます。
リモートログインタイムアウトを300秒に設定します。
sp_configure 'remote login timeout', 300
go
reconfigure with override
go
リモートクエリのタイムアウトを0(無限待機)に設定します。
sp_configure 'remote query timeout', 0
go
reconfigure with override
go
更新:SQL Server 2012 SP1以降:SELECT
権限のあるユーザーがアクセスできるようになりDBCC SHOW_STATISTICS
、リンクサーバーでの読み取り専用のパフォーマンスが向上します。参照:https : //msdn.microsoft.com/en-us/library/ms174384(v=sql.110).aspx
アップデート:それはデータのサイズや接続速度ではないと言って正しいです。それは私の霧の中でベルを鳴らし、私はそれをどこで見たのかを思い出しました:アプリケーションで遅い、SSMSで速い?(リンクサーバーの問題)。これはパラメータースニッフィングではなく、(権限が原因で)欠落している統計自体であり、不適切なクエリプランが使用されます。
見積もりが異なることがわかります。sysadminとして実行した場合、Northwindには注文IDが20000を超える注文がないため、推定値は1行でした。これは正しい数値です。しかし、通常のユーザーとして実行した場合、推定値は249行でした。この特定の数値は、830注文の30%、またはオプティマイザに情報がない場合の不等式操作の推定値として認識されます。以前は、これは不明な変数値が原因でしたが、この場合、不明である可能性のある変数はありません。いいえ、欠けているのは統計そのものです。
クエリがローカルサーバーのテーブルのみにアクセスする限り、オプティマイザは常にクエリ内のすべてのテーブルの統計にアクセスできます。追加の権限チェックはありません。ただし、これはリンクサーバー上のテーブルとは異なります。SQL Serverがリンクサーバーにアクセスする場合、サーバー間通信にのみ使用されるシークレットプロトコルはありません。いいえ、代わりに、SQL Serverはリンクサーバーの標準OLE DBインターフェイスを使用し、他のSQL Serverインスタンス、Oracle、テキストファイル、または自作のデータソースであり、他のユーザーと同じように接続します。統計が正確に取得される方法は、データソースと問題のOLE DBプロバイダーによって異なります。この場合、プロバイダーはSQL Server Native Clientで、2つのステップで統計を取得します。(これは、リモートサーバーに対してプロファイラーを実行することで確認できます)。最初に、プロバイダーは、sp_table_statistics2_rowsetプロシージャを実行します。これは、存在する列統計に関する情報、およびそのカーディナリティと密度情報を返します。2番目のステップでは、プロバイダーはDBCC SHOW_STATISTICSを実行します。これは、完全な分散統計を返すコマンドです。(この記事の後半で、このコマンドについて詳しく説明します。)ここで問題点を説明します。DBCCSHOW_STATISTICSを実行するには、サーバーロールsysadminまたはデータベースロールdb_ownerまたはdb_ddladminのメンバーである必要があります。
そして、これが私が異なる結果を得た理由です。sysadminとして実行すると、注文ID> 20000の行がないことを示す完全な分散統計が得られ、見積もりは1行でした。(オプティマイザが統計からゼロ行を想定することは決してないことを思い出してください。)しかし、プレーンユーザーとして実行すると、DBCC SHOW_STATISTICSはアクセス許可エラーで失敗しました。このエラーは伝播されませんでしたが、代わりにオプティマイザは統計がないことを受け入れ、デフォルトの仮定を使用しました。カーディナリティ情報を取得したため、リモートテーブルには830行あり、推定では249行あることがわかりました。
リンクサーバーへのアクセスを含むクエリがアプリケーションで低速であるパフォーマンスの問題が発生したが、SSMSからテストすると高速に実行される場合は、リモートデータベースに対する不十分なアクセス許可が原因であるかどうかを常に調査する必要があります。(リンクサーバーへのアクセスはクエリでは明白ではないかもしれませんが、ビューでは非表示である可能性があることに注意してください。)リモートデータベースのアクセス許可が問題であると判断した場合、どのようなアクションを実行できますか?
ユーザーをロールdb_ddladminに追加できますが、これにより、ユーザーにテーブルを追加および削除する権利が与えられるため、これはお勧めできません。
既定では、ユーザーがリモートサーバーに接続するとき、ユーザーは自分自身として接続しますが、sp_addlinkedsrvloginを使用してログインマッピングを設定し、ユーザーがdb_ddladminのメンバーシップを持つプロキシアカウントにマップするようにすることができます。このプロキシアカウントはSQLログインである必要があるため、リモートサーバーでSQL認証が有効になっていない場合、これはオプションではありません。この解決策もセキュリティの観点からは少し疑わしいですが、以前の提案の方が優れています。
場合によっては、OPENQUERYを使用してクエリを書き換え、リモートサーバーでの評価を強制することができます。これは、クエリに複数のリモートテーブルが含まれている場合に特に便利です。(ただし、オプティマイザがリモートサーバーから取得する統計情報がさらに少なくなるため、逆効果になることもあります。)
もちろん、ヒントと計画ガイドの完全なバッテリーを使用して、必要な計画を取得することもできます。
最後に、リンクサーバーへのアクセスが必要かどうかを自問する必要があります。データベースが同じサーバー上にある可能性はありますか?データを複製できますか?他の解決策はありますか?