16

私はしばらくの間SQLServerでCLRストアプロシージャを使用してきましたが、それを使用するのに最適な状況は何であるかまだ疑問に思っています。

MSDNは、重い文字列操作(regex)や、多くのテーブル変数とカーソルを宣言するT-SQLの置き換えなどの使用に関するガイドラインを提供しています。SOユーザーがCLRストアドプロシージャでどのような問題を解決しているのか、また例/ベンチマークについても知りたいです。

たとえば、CLRストアドプロシージャ+ SSRSは、データ操作ロジックをSSRSおよびT-SQLから、読み取りと操作がより簡単なマネージコードに取り込むための優れた方法であることがわかりました。

4

6 に答える 6

23

非正規化やシーケンシャル操作を必要とする多くの問題は、CLR によって非常にうまく処理でき、SQL 側での使いやすさを (大幅に) 犠牲にすることなく、パフォーマンスを劇的に向上させるために使用できます。セットベースまたは反復操作のいずれかに完全に依存する代わりに、ハイブリッド アプローチを採用し、大量輸送にはセットベースのソリューションを使用し、タイト ループには反復モデルに切り替えることができます。

SQL Server 2008の組み込み型hierarchyidと地理空間型 (つまりgeography) は、非正規化の問題の良い例です。どちらも (ほぼ) 任意に大量のデータを含んでおり、パフォーマンスを損なうことなく正規化することは困難です。それ以外の場合は、再帰またはカーソルを使用して意味のある作業を行うか、ラットのトリガーのネストおよび/またはスケジュールされたタスクを使用する必要があります。非正規化テーブルを維持します。

私が CLR 型で解決したもう 1 つの問題は、インライン圧縮です。これは無意味または学術的な演習のように聞こえるかもしれませんが、完全に正規化されたデータがテラバイトに達する場合、サイズが 80 ~ 90% 削減されることは大きな意味があります。現在、SQL には独自の圧縮機能が組み込まれており、SQL 2005 には vardecimal がありました。これらも優れたツールですが、ドメイン対応の「最小化」アルゴリズムは、CPU 負荷と圧縮率の両方の点で数倍効率的です。もちろん、これはすべての問題に当てはまるわけではありませんが、一部の問題には当てはまります。

このサイトでよく見られるもう 1 つの非常に一般的な問題は、連続した日付のシーケンスなど、オンザフライでシーケンスを生成することです。一般的なソリューションは、再帰 CTE、静的シーケンス テーブル、あまり知られていないspt_valuesテーブルですが、単純な CLR UDF はそれらのいずれよりも優れたパフォーマンスを発揮し、柔軟性が大幅に向上します。

最後に: ユーザー定義のストリーミング集計も、特に統計関連の場合に非常に役立ちます。中央値、加重移動平均など、組み込みの SQL 集計から単純に構成できないものがいくつかあります。UDA は複数の引数を取ることもできるため、それらをパラメーター化できます。技術的には、現在のバージョンの SQL Server では集計が特定の順序でデータを受け取ることが保証されていませんがROW_NUMBER、追加の引数として集計をフィードし、これを使用してほぼすべてのウィンドウ関数を実装することで、その制限を回避できます (集約はUDTを吐き出し、それをテーブルに変換できます)。

本当に役立つ SQL-CLR アプリケーションの例がほとんどないことは、実際には非常にイライラさせられます。Google で検索すると、1,000 万件の結果が得られます。そのすべてが、ばかげた文字列連結または正規表現です。これらは便利ですが、特に SQL UDT と UDA について学習するのに数分かかります。独自のアプリケーションでこれらが多く使用されていることに気付くでしょう。もちろん、気を悪くしないでください。純粋な SQL でより良い解決策があるかどうかを慎重に考えてください。ただし、それらを軽視しないでください。

于 2010-01-26T19:50:19.463 に答える
5

文字列操作-正規表現検索は古典的です。CLRでの公開は非常に簡単で、ストレートT-SQLでの公開は非常に困難です。

実装とマイクロベンチマークの詳細については、このリンクを参照してください( SQLCLR is only 47 milliseconds compared to 6.187 seconds for the T-SQL UDF)。

于 2010-01-26T17:03:28.903 に答える
5

文字列操作 (正規表現) については既に言及しましたが、DateTime 算術演算、そしてもちろん別の大物 (外部 Web サービスの呼び出し) についても触れました。

于 2010-01-26T17:06:07.150 に答える
3

以下は、私が CLR プロシージャを使用した例です。

CLR ストアド プロシージャと SQL ジョブを使用した、外部 Web サービスからの時間指定されたデータ更新。

追跡するデータの一部を外部の業界データ フィードと同期するアプリケーションがあります。同期はすべてに対して毎週実行され、単一の更新に対してもオンデマンドで実行されるため、アクセスするための既存の Web サービス API がありました。物事は既に Windows サービスによってスケジュールされていますが、なぜ他の SQL ジョブのようにスケジュールできないのでしょうか??

アプリケーションの Web サービス API を参照する CLR ストアド プロシージャを作成しました。次に、単一の同期をサポートするために @RecordID のパラメーターをいくつか追加し、エンタープライズ マネージャーの SQL ジョブでスケジュールを設定しました。

これで、Job を使用して dB 同期を実行したり、他の SQL proc または Triggers 内で proc を使用して外部フィードからデータを更新したりできます。

将来的には、アプリケーション Web サービス API を取り出して、外部 Web サービスを直接使用する方がクリーンになる可能性があります。今のところ、これは非常に迅速に実装でき、機能を SQL グループに拡張するクールな方法でした。

于 2010-01-27T19:44:02.483 に答える
2
  • カスタム集計
  • 文字列操作
  • カスタム データ型

正直に言うと、CSV を行に分割することを含む文字列処理しか見ていません。

私がDBAタイプのことをしているDBAでない限り、デフォルトの信頼レベルを超える必要があるものはすべて範囲外であると考えています。

MSDN と RegEx および RSS フィードの例から: Using CLR Integration in SQL Server 2005

于 2010-01-26T18:32:22.850 に答える
1

これは、従来の SQL インターフェースを提供しないシステムや、ベンダーによるそのインターフェースの実装が標準以下のシステムからデータを引き出すのに非常に役立ちます。

古い MUMPS プラットフォーム上に構築されたコア アプリケーションがあり、Intersystems キャッシュ データベース上で実行されます。データは階層的であり、本質的にリレーショナルではありません。メインのグローバル配列 (つまり、テーブル) には、複数のデータ レベルと要素がすべて口座番号ごとにグループ化されています。1 つの列をスキャンするだけでも、グローバル全体をディスクからロードする必要があり、8 時間以上かかります。ベンダーは、ODBC ドライバーとグローバルへのマッピングを提供していますが、多くの場合、スキャンが発生し、クエリが非常に遅くなります。

ObjectScript (Intersystem の MUMPS の方言) プログラムを受け取り、それをキャッシュ サーバー上で実行し、出力行をデータ行として返すテーブル値関数を作成しました。MUMPS 側で実行する特定のプログラムを提供することで、MUMPS 側のデータ アクセス パスを細かく管理できます (これは、効率的なデータ アクセスを取得するために実際に必要なことです)。MSSQL のデータをアドホック インライン データ ソースとして簡単にインポートできます。

TVF を使用してデータ選択CROSS APPLYを実行したり、相手側で検索を行ったりすることができ、かなり効率的です。MSSQL で並列実行プランを使用するように強制すれば、リモート エンドで複数のクエリを並列に実行することもできます。

于 2013-01-29T16:24:20.430 に答える