SQL 2005 以降では、TSQL ストアド プロシージャよりも CLR ストアド プロシージャが優先されますか?

StackOverflow https://stackoverflow.com/questions/58190

  •  09-06-2019
  •  | 
  •  

質問

私の現在の見解は「ノー」です。Transact SQL ストアド プロシージャは軽量で (おそらく) パフォーマンスが高いオプションであるため、Transact SQL ストアド プロシージャを優先します。一方、CLR プロシージャでは開発者があらゆる種類のいたずらに対処できるからです。

しかし最近、非常に貧弱に書かれた TSQL ストアド プロシージャをデバッグする必要がありました。いつものように、元の開発者に実際の TSQL の経験がなく、ASP.NET / C# に焦点を当てていたため、問題の多くが見つかりました。

したがって、CLR プロシージャを使用すると、第一に、このタイプの開発者にとってより使い慣れたツールセットが提供され、第二に、デバッグおよびテスト機能がより強力になります (つまり、SQL Management Studio ではなく Visual Studio)。

それは簡単な選択ではないようなので、あなたの経験を聞きたいです。

役に立ちましたか?

解決

よく考えられ、よく書かれた T-SQL と CLR の両方に適した場所があります。一部の関数が頻繁に呼び出されず、SQL Server 2000 の拡張プロシージャが必要な場合は、CLR がオプションになることがあります。また、データのすぐ隣で計算などを実行できるのも魅力的かもしれません。しかし、新しいテクノロジーを投入して悪いプログラマーを解決するというのは、悪い考えのように思えます。

他のヒント

CLR ストアド プロシージャは、セットベースのクエリを置き換えることを目的としたものではありません。データベースにクエリを実行する必要がある場合でも、通常のコードに SQL が埋め込まれているかのように、CLR コードに SQL を組み込む必要があります。これでは努力が無駄になってしまいます。

CLR ストアド プロシージャは、主に次の 2 つの目的に使用されます。1) OS との対話 (ファイルからの読み取りや MSMQ へのメッセージのドロップなど)、2) 複雑な計算の実行 (特に計算を行うためのコードが .NET 言語で記述されている場合)。

SQL Server 内で CLR をホストすることは、データベース開発者に次のことを提供することを目的としています。 より柔軟なオプション 彼らがどのようにして任務を達成しようとしたのか。他の人が述べたように、SQL は操作や変更に最適です。 データセット. 。複雑なビジネス/ドメイン ルールを使用した広範な大規模アプリケーション開発を行ったことがある人なら、おそらくこう言うでしょう。純粋な SQL を使用して (場合によっては単一のマクロ クエリに) これらのルールの一部を適用しようとすると、本当に悪夢のような結果になる可能性があります。

一部のタスクは、手続き型またはオブジェクト指向の方法で処理したほうがよい場合があります。.NET コードを使用してロジックのシーケンスを分割することを選択できることにより、クエリ操作の読み取りとデバッグが容易になります。CLR ストアド プロシージャを使用した経験があると、デバッガーを使用してステップを実行すると、データベース レベルで何が起こっているかを追跡するのが本当に簡単になることがわかります。

ほんの一例ですが、ここでは動的検索クエリの「ゲートウェイ」として CLR ストアド プロシージャを頻繁に使用します。最大 30 個の異なる検索パラメーターを含めることができる検索リクエストを言います。ユーザーは明らかに 30 個すべてを使用するわけではないため、渡されるデータ構造には 30 個のパラメーターがありますが、ほとんどが DBNULL です。クライアント側には、 オプションはありません 明らかなセキュリティ上の理由から、動的ステートメントを生成します。結果として得られる動的ステートメントは、外部の「追加機能」を恐れることなく内部的に生成されます。

一般に、データベースとのインターフェースをあまり必要としないものがある場合は CLR を使用します。したがって、値を解析またはデコードしているとします。これは CLR で実行して値を返す方が簡単です。

CLR で複雑なクエリを実行しようとすることは、適切な方法ではありません。

ところで、これは2008年でも変わりませんでした。

この二つは同等ではないと思います...互いに直角になるようにフィットします。
CLR Integration は、以前の「拡張ストアド プロシージャ」を段階的に廃止することになっています。 うちの職場にもいくつかありますが…本質的には、従来の DB ストアド プロシージャ/T SQL では実行が困難/不可能だった SQL データに対する処理/ロジックのブロックです。そこで彼らは、同様に呼び出すことができる C++ DLL の拡張ストアド プロシージャとしてそれを作成しました。現在、それらは段階的に廃止され、CLR 統合が代替品となります。

  • DB ストアド プロシージャ:T SQL ストアド プロシージャで実行できる場合は、実行してください。
  • CLR ストアド プロシージャ:ロジックが複雑すぎるか、T SQL で実行するには面倒な場合...CLR コードの行数が少なくて済むもの (文字列操作、複雑な/カスタムの並べ替えやフィルター処理など) の場合は、このアプローチを使用します。

ファイル システム アクセス (CLR プロシージャの利点が非常に顕著な場合) を除けば、私は T-SQL プロシージャを使用します。特に複雑な計算がある場合は、その部分を CLR に入れることができます。 関数 そしてこれをプロシージャ内から呼び出します(CLR統合が本当に優れていることが私が発見した場所はudfです)。そうすれば、タスクの特定の部分で CLR 統合のメリットが得られますが、ストアド プロシージャ ロジックをできる限り DB に保持できます。

あなたが言ったことを考えると、CLR で t-sql タスクを実行できるようにして、おそらくパフォーマンスにさらに多くの損害を与えるよりも、開発者に t-SQl とデータベース全般について適切なトレーニングを受けてもらいたいと思います。データベースを理解していない開発者は、データベースのパフォーマンスに最適な方法で物事を行うことを避ける言い訳としてそれを使用します。彼らは、より簡単だと思われる方法を選択したいからです。

結局のところ、仕事に適したツールが常に重要になるため、それは実際に何を達成しようとしているかによって異なります。

ただし、一般的なルールとして、CLR プロシージャのオーバーヘッドが大きく、T-SQL のようなセット操作を実行しないというのは正しいことです。私のガイドラインは、T-SQL で必要なものが過度に複雑にならない限り、すべてを T-SQL で行うことです。次に、T-SQL アプローチを機能させるためにさらに努力してください。:-)

CLR proc は優れており、確かにその役割を果たしていますが、その使用は原則ではなく例外であるべきです。

SQL Server Books Online の 件名に関するページ に次の利点を示します。

  • より優れたプログラミング モデル。 .NET Framework 言語は多くの点で Transact-SQL よりも豊富で、これまで SQL Server 開発者が利用できなかった構造と機能を提供します。開発者は、プログラミングの問題を迅速かつ効率的に解決するために使用できる広範なクラスのセットを提供する .NET Framework ライブラリの機能を活用することもできます。

  • 安全性とセキュリティの向上。 マネージド コードは、データベース エンジンによってホストされる共通言語ランタイム環境で実行されます。SQL Server はこれを利用して、以前のバージョンの SQL Server で利用可能な拡張ストアド プロシージャに代わる、より安全で安全な代替手段を提供します。

  • データ型と集計関数を定義する機能。 ユーザー定義型とユーザー定義集計は、SQL Server のストレージ機能とクエリ機能を拡張する 2 つの新しいマネージド データベース オブジェクトです。

  • 標準化された環境による開発の合理化。 データベース開発は、Microsoft Visual Studio .NET 開発環境の将来のリリースに統合されます。開発者は、中間層またはクライアント層の .NET Framework コンポーネントとサービスを作成するために使用するのと同じツールを、データベース オブジェクトとスクリプトの開発とデバッグに使用します。

  • パフォーマンスとスケーラビリティが向上する可能性。 多くの状況で、.NET Framework 言語のコンパイルおよび実行モデルは、Transact-SQL よりもパフォーマンスが向上します。

通常の SQL プロシージャで CLR 関数が何千回も呼び出されるという状況に遭遇しました。これは、別のシステムからデータをインポートするためのプロシージャでした。この関数はデータを検証し、null を適切に処理しました。

TSQL で操作を実行した場合、proc は約 15 秒で完了しました。CLR 関数を使用した場合、処理は 20 ~ 40 分で完了しました。CLR 関数はよりエレガントに見えましたが、私たちが知る限り、CLR 関数を使用するたびに起動ヒットがありました。したがって、1 つの CLR 関数を使用して大規模な操作を実行する場合、起動時間は操作にかかる時間に比べて短いため、問題ありません。または、CLR 関数の呼び出し回数が控えめであれば、関数のすべての呼び出しの合計起動時間は短くなります。ただしループには注意してください。

また、保守性を考えると、本当に必要以上の言語を使用しないほうが良いでしょう。

CLR を使用する理由として、言及されていない可能性のあるいくつかの理由を付け加えます。

  • 基本的なクエリ関数、非クエリ関数、およびスカラー SQL 関数を置き換えて拡張します。
    A) エラーレポートとアラートは、定義された要件に基づいて統合できます。B) デバッグ レベルを簡単に定義します。C) 外部 SQL サーバーと対話する簡単な方法を有効にする
  • レガシーコードを管理された環境に移動します。

同様の質問に対して次の回答を投稿しました。 SQL SERVER CLR の利点。ただし、C# / VB.net / などは T-SQL よりも使い慣れている言語であることを付け加えておきます。 ない これが、T-SQL ではなく SQLCLR を使用する理由になります。T-SQL で何かを達成する方法がわからない場合は、まず T-SQL ソリューションを見つけるために助けを求めてください。存在しない場合は、 それから CLRルートに進みます。


SQL Server 内での SQLCLR / CLR 統合は、特定の (すべてではない) 問題の解決に役立つツールの 1 つにすぎません。純粋な T-SQL で実行できることよりも優れた機能がいくつかあり、SQLCLR を介してのみ実行できる機能もいくつかあります。SQL Server Central の記事を書きました。 SQLCLR レベル 1 への階段:SQLCLRとは何ですか? (そこで記事を読むには無料の登録が必要です)、この質問に答えます。基本は次のとおりです (詳細については、リンク先の記事を参照してください)。

  • ストリーミング テーブル値関数 (sTVF)
  • 動的SQL (関数内)
  • 外部リソースへのアクセスの向上 / xp_cmdshell の置き換え
    • データの受け渡しが簡単になる
    • 結果セットの複数の列を取得するのが簡単になります
    • 外部依存関係はありません (例:7zip.exe)
    • 偽装によるセキュリティの向上
  • マルチスレッド機能
  • エラー処理 (関数内)
  • カスタム集計
  • カスタムタイプ
  • 状態の変更 (関数内および関数外) OPENQUERY / OPENROWSET)
  • ストアド プロシージャを実行します (読み取り専用。関数内と関数外 OPENQUERY / OPENROWSET)
  • パフォーマンス (注記: これは ない すべての場合に意味しますが、操作の種類と複雑さに応じて場合によっては必ず意味します)
  • 出力をキャプチャできます (つまり、SSMS の [メッセージ] タブに送信される内容) (例: PRINT そして RAISERROR とともに 重大度 = 0 ~ 10) -- 記事内でこれについて言及するのを忘れていました ;-)。

もう 1 つ考慮すべきことは、アプリ コードにアクセスするためだけにカスタムの内部専用画面を構築することなく、DB が特定のビジネス ロジックを洞察できるように、アプリと DB の間でコードを共有できることが有益な場合があることです。たとえば、私は顧客からデータ ファイルをインポートし、ほとんどのフィールドのカスタム ハッシュを使用して、その値を DB の行に保存するシステムに取り組んできました。これにより、アプリが入力ファイルの値をハッシュし、行に保存されているハッシュ値と比較するため、データを再度インポートするときに行を簡単にスキップできるようになりました。それらが同じであれば、どのフィールドも変更されていないことがすぐにわかり、次の行に進みました。これは単純な INT 比較でした。ただし、ハッシュを実行するためのアルゴリズムはアプリのコード内にのみ存在するため、顧客のケースをデバッグするためであっても、少なくとも 1 つのフィールドに変更があった行にフラグを付けることで一部の処理をバックエンド サービスにオフロードする方法を探している場合でも(アプリからの変更)新しいインポート ファイル内の変更を探すのではなく)、私にできることは何もありませんでした。これは、たとえ通常の処理ではなかったとしても、DB にかなり単純なビジネス ロジックを含める絶好の機会だったでしょう。DB 内にエンコードされた値に相当するものが存在し、その意味を理解できないと、問題を解決することが非常に困難になります。

コードを書かずにこれらの機能の一部を実際に確認したい場合は、無料版の SQL# (私が作成者です) には RegEx 関数、カスタム集計 (UDA)、カスタム タイプ (UDT) などが含まれています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top