9

職場には 2 台のサーバーがあり、1 台は SQL Server 2000 バックエンドを持つ、多くの人が使用するアプリケーションを実行しています。私は長い間これを自由に照会してきましたが、ストアド プロシージャや追加のテーブルなどを追加することはできません。

これにより、最初の SQL Server にリンクされた 2 つ目の SQL Server を持つことになり、リンク サーバーを使用して両側からデータをクエリするストアド プロシージャのライブラリを構築しました。これらのクエリの一部は、希望よりも時間がかかっています。

リンク サーバーの使用に関する優れた記事を教えてもらえますか? 通常、SQLステートメントの大部分はリモートで実行できるため、2つの間でどのデータが転送されているかを知ることに特に興味がありますが、テーブル全体を転送している可能性があると感じています。通常は小さな最終への結合ですテーブルをローカルに。

また、現在私が持っているリンクサーバーオプションは何ですか:

  • 照合互換 True
  • データ アクセス True
  • Rpc True
  • Rpc アウト True
  • リモート照合を使用する False
  • 照合名(空白)
  • 接続タイムアウト 0
  • クエリ タイムアウト 0

編集:

この投稿を更新しようと思ったのですが、パフォーマンスを向上させるためにしばらくの間、動的パラメーターを使用して openqueries を使用しました。ヒントをありがとう。ただし、これを行うと、文字列を処理することになるため、クエリがより面倒になる可能性があります。ついにこの夏、SQL Server を 2008 にアップグレードし、ライブ データ ミラーリングを実装しました。正直なところ、オープン クエリは私のタスクのローカル クエリの速度に近づいていましたが、ミラーリングにより、SQL の処理が確実に簡単になりました。

4

9 に答える 9

8

リンク サーバー テーブルへの結合は避けてください。

結合に 4 部構成の命名を使用することもできますが、コストが高くなります。結合には、リンク サーバーからのデータ セットを制限し、インデックス付きの列を使用するために使用できる条件を含めることができます。

例:

SELECT loc.field1, lnk.field1
FROM MyTable loc
INNER JOIN RemoteServer.Database.Schema.SomeTable lnk
  ON loc.id = lnk.id
  AND lnk.RecordDate = GETDATE()
WHERE loc.SalesDate = GETDATE()

このクエリは、結合が計算される前にリンク サーバーで使用できる結合条件も適用しています。

推奨される方法は、OPENQUERY の使用です。

OPENQUERY を使用して結合を回避することにより、ローカル サーバーは、結合用の一連の ID を送信する代わりに、リモートで実行されるクエリのみを送信します。

リンクを使用して一連のデータを取得し、計算をローカルで実行します。一時テーブル (アドホック クエリの場合) を使用するか、夜間ジョブで永続テーブルに行を挿入します。

好きなサーバーにリモート トランザクション コーディネーターが設定されているかどうかによっては、トランザクションの開始に失敗する場合があります。それを使用すると、より多くのリソースが消費されます。

また、アプリケーションを実行している実稼働サーバーにヒットしていることを考慮してください。指定していませんが、大量のトランザクションを使用し、挿入と更新を行っていると想定しても安全だと思います。アプリケーションからリソースを奪っています。

あなたの目的は、レポート目的でデータを使用することのようです。サーバーは、完全ではなく単純なログを持つように設定して、より効率的にすることができます。

また、リンク サーバーでのデータ移動が原因でクエリがキャンセルされることも回避できます。クエリや NOLOCK などのテーブル ヒントに適切な分離レベルを設定するよう常に注意してください。

そしてどうぞ!OPENQUERY (または任意のリンク サーバー) をループ内に配置しないでください。

于 2008-09-27T05:53:25.940 に答える
3

このような結合にリンク サーバーを使用する場合、すぐに接続する (「ローカル」) サーバーを、ほとんどのデータを保持するサーバーにすることが重要です。リンク サーバーはデータのごく一部しか提供しません。 、それ以外の場合は、結合を実行するために必要なだけのデータをプルします。

別の方法としては、データのサブセットを一時テーブルにコピーして、結果をスリム化するためにできるだけ多くの作業を行い、リンク サーバーが実行できる前処理を行ってから、"ローカル" 側で結合を実行します。

方法を逆にして、制御できないサーバーに接続し(リンクサーバーを作成する必要があります)、リンクを介してサーバーに接続することで、パフォーマンスを簡単に向上させることができる場合があります。sprocs を作成しなければならないようなデータで主要な作業を行う必要がある場合は、データをサーバーにプッシュし、そこで sprocs を使用します。

場合によっては、リンク サーバーにこの種の要約を毎晩作成させ、それをローカル サーバーにプッシュしてから、ローカル サーバーが結合で作業を実行するようにしました。

于 2008-09-25T14:02:54.840 に答える
3

ロイヤル ペイン

私たちのショップにはいくつかのリンクされたサーバーがありましたが、そのような PITAであることが判明しました。

まず第一に、あなたが説明したものと同様の深刻なパフォーマンスの問題がありました. ネットワーク I/O 統計を見てショックを受けました。あらゆる努力にもかかわらず、SQL Server を合理的な動作に誘導することはできませんでした。

もう 1 つの問題は、ストアド プロシージャでは、これらのリンク サーバー名がどこにでもハードコードされており、上書きする方法がないことでした。そのため、開発者は、リンク サーバーに関係する機能を開発サンドボックスで簡単にテストできませんでした。これは、普遍的に使用できる単体テスト スイートを作成する上での大きな障害でした。

最終的に、リンク サーバーを完全に廃止し、データ同期を Web サービスに移行しました。

于 2008-09-26T23:19:27.043 に答える
2

リンク サーバー全体で準結合を含むクエリは、あまり効率的ではない傾向があります。OPENQUERYを使用してローカルの一時テーブルにデータを入力し、そこから作業する方がよい場合があります。

于 2008-09-25T09:30:23.793 に答える
1

数年前に SQL 2000 でリモート リンク サーバー アプリケーションを作成しましたが、あなたが説明したのと同じパフォーマンスの問題に遭遇しました。最高のパフォーマンスを得るために、ストアド プロシージャを何度か書き直すことになりました。

私は一時テーブルを広範囲に使用しました。大量のリモート データを一時テーブルに取得し、それに結合して操作する方が安価であることがわかりました。ローカル テーブルからリモート テーブルへの結合は、ご指摘のとおり非常に低速でした。

実行計画の表示と推定実行計画の表示は、私が見ているものの多くを理解していませんでしたが、役立つ傾向がありました。

リモート サーバーでこれらのクエリを実行する効率的な方法が実際にあるかどうかはわかりません。SQL Server は、リンク サーバーに対して通常の最適化を利用できないように思われるからです。実際にそれが起こっているので、テーブル全体を転送しているように感じるかもしれません。

レプリケーションのシナリオがうまくいくかどうか疑問に思っています。ローカル サーバーにデータを保持することで、必要に応じて実行される通常のクエリを記述できるようになります。

あなたを指し示す良い記事を知りません。より複雑な SQL Server アプリケーションを作成するにつれて、SQL Server がその下でどのように機能するかをよりよく理解する必要があると考えるようになりました。そのために、Kalen Delaney が編集した MS Press Inside Microsoft SQL Server 2005 シリーズを購入しました。第 1 巻: ストレージ エンジンは間違いなく出発点ですが、私はそこまで踏み込んでいません。私の最近のいくつかのプロジェクトには SQL Server が含まれていなかったため、SQL Server に関する私の研究は手抜きになりました。

于 2008-09-26T21:38:19.580 に答える
0

リンクサーバーを使用するのではなく、サーバー上に別のデータベースをセットアップできる可能性はありますか?

于 2008-09-25T15:29:43.680 に答える
0

動的 SQL と関数を使用して、ハードコーディングされた名前の質問を回避できます。たとえば、関数 ufn_linkedDatabase(@purpose nvarchar(255)) と入力 'cpi.cpi' (目的 CPI、サブ目的のデフォルト) が '[SERVER-NAME.DOMAIN.LCL,2000] を返す実装を試みています。 [CPI]' 運用環境 (SQL Server の代替ポート番号を使用する場合、リンク サーバー名を含め、理由はわかりません)。次に、リンクされたサーバーとデータベースを表す式 @{cpi.cpi} を使用して @template varchar(max) に SQL コマンドがアセンブルされ、次に @workstring = REPLACE(@template, N'@{cpi.cpi}', . ..) . 関数が実際にデータベース名を取得する方法は、手順とは別のものです。ルックアップ テーブルが便利です。

問題 - OPENQUERY() を実行します。これは、リンク サーバーでより多くのタスクを実行できるように、リンク サーバー オプションの「照合互換性」が「true」に設定されていない限り、少なくともより良い方法です。高速ネットワークでも重要です。サーバー ルームの内部ネットワークはかなり高速です。そして、この設計を使用してアプリケーションを 1 つだけ作成することになる可能性があります。その場合、過剰に設計されています。それでも、関数自体は特別な作業である必要はありません。

とにかく、問題に高速なネットワーク ハードウェアを投入するのが、安上がりな答えかもしれません。

于 2009-08-03T15:30:16.267 に答える
0

リンクされた結合の代わりに、カーソルループで動的なオープンクエリをお勧めします。これは、私が MS Access のリンク結合のパフォーマンスを複製することができた唯一の方法です (少なくとも単一のリモート テーブルの場合)

-- カーソル ループ内での openqueries の何が悪いのか知りたいですか? 正しく行われれば、ロックの問題はありません。

于 2008-09-30T15:04:14.983 に答える
0

これは非常に寛大な問題であり、多くの解決策がある可能性があります。しかし、非常に多くのユーザーがすべてを試したと言っているのを目の当たりにしてきました.

私の問題を解決したのは..

SQL Server 2000 を SP2 から SP4 にアップグレードしました。既に SQL Server 2000 に SP4 がある場合は、Instcat.sql を実行します。私の経験によると、他のすべての回避策で疲れ果てている場合でも、これは確実に機能することを保証できます。

ありがとう、ミタレシュ mithalesh.gupta@gmail.com

于 2009-07-20T07:10:44.887 に答える