web-dev-qa-db-ja.com

CRUDのエンティティフレームワークを使用して、ハイエンドクエリに伴う複雑さをデータベースで処理する必要がありますか?

単純な追加、削除関数で置き換えることにより、一般的なクエリを作成するオーバーヘッドを削減するため、私はefを初めて使用し、気に入っています。同意した。

今日、私はしばらくそれを使用している私の同僚との議論に入り、ストアドプロシージャをいつ使用するのか、いつEFを使用するのか、そして何をするのかについてアドバイスを求めました。

彼は返事をした;

見て、単純なことは両方を使用できることですが、データベース、つまりストアドプロシージャですべてを実行する場合にORMを使用する意味は何ですか。それで、どこで何をすべきか、そしてその理由をどのように理解しますか? 3から4の結合を必要とするすべてのCRUD操作とクエリにORMを使用することを学習した単純な式ですが、それを超えるとストアドプロシージャを使用する方が適切です。

私は考え、分析し、回答しました。

まあ、これはそうではありません、私は人々がEFで大規模なことをやっていて、手順を書く必要がないブログや例を見てきました。

しかし、彼は頑固でパフォーマンスのオーバーヘッドと呼んでいますが、私は彼に比べて比較的新しいので、まだ理解できていません。

したがって、私の質問は、CRUDをefで処理するだけでよいのか、それともストアドプロシージャの代わりとしてEFでもっと多くのことを行うべきなのかということです。

4
azure boy

私はその件についてあなたのアプローチをとる傾向があります。 ORMは基本的なCRUDや比較的単純なクエリには最適ですが、通常はパフォーマンス上の理由から、データベースに直接アクセスすることを好むことがよくあります。

SQL Serverで複雑なビュー(またはsproc)を記述して、Linqで行うよりもはるかに簡単に最適化できます。一方、実際のロジックをデータベース内に配置することに注意することも正しいと思います。

ORMはデータベースとやり取りするための1つのツールであり、日常の作業では、SQLステートメントを作成するのではなく、非常に単純化できます。しかし、他のほとんどすべてのツールの場合と同様に、DBの相互作用を完全に置き換えることは特効薬ではありません。

ここで私が従う2つのルールがある傾向があります。

  1. ビジネスロジックの計算ではなく、パフォーマンスの最適化の理由で直接DBオブジェクトのみを使用することを試みます(2つのクロスパスの場合もありますが、多くの場合、実際の論理セットを実行する.NETメソッドのソースとしてベースビュー/ sprocを生成できます)比較)、そして...
  2. DBContextクラス/リポジトリクラスを使用して、これらの最適化の目的で作成したビュー/ sprocを呼び出します。つまり、標準のEF DBSetを取得するDBContextクラスがある場合は、そこで「サポートオブジェクト」への呼び出しを公開して使用する必要があります(したがって、sproc _dbo.GenerateReportSet_は、たとえば_context.GenerateReportSet(dateStart, dateEnd)
2
jleach

しかし、彼は頑固で、それをパフォーマンスオーバーヘッドと呼んでいますが、それはまだ私の理解を超えています

問題の冒頭の一部を理解していない(したがって認められない)場合、何かについて詳細な議論をすることは困難です。

非常に簡単に言えば、自動化はそれほど賢いことです。複雑で複雑なクエリを処理する場合、EFは有効なクエリを生成しますが、期待するほど効率的ではありません。
EFはそれほど開発されていません。生成された非効率的なクエリは、EFが実行するように構築されている(および構築されていない)ことの避けられない結果にすぎません。 EFは、簡単で反復的なコードを回避する優れたツールです。しかし、高度にカスタマイズされた(一般に複雑な)クエリを処理している場合、これらの利点は失われます。

このように考えてみてください。私のセダンは道路で使用するために作られています。路上では、大型の4x4よりも運転がはるかに簡単になります。車をオフロードすることはできますか?はい、理由があります。しかし、私の車はオフロード用に作られたものではないので、道路を走っていないと車の利点が失われますが、4x4は輝き始め、オフロードでの運転が容易になります。
私の車が道路用に作られているように、EFは単純なCRUDタスク用に作られています。他の方法で使用することもできますが、それを念頭に置いて設計した人は誰もいません。

「簡単に言うと、両方を使用できるということですが、データベース、つまりストアドプロシージャですべて実行する場合、ORMを使用する意味は何ですか。」

その議論はほとんど意味がありません。とにかく腕を動かして歯ブラシを動かすのなら、歯ブラシを使う意味は何でしょう。腕を使って歯をきれいにしてください!

まあ、これはそうではありません、私は人々がEFで大規模なことをやっていて、手順を書く必要がないブログや例を見てきました。

それができるからといって、それがうまく行われているということではありません。私が作った料理を他の人が食べるのを見てきましたが、私が料理が上手だということではありません。それは、私が料理をするのに十分ではないことを意味します。

EFは多くのことを実行できますが、クエリの複雑さが増すにつれてEFの効率は低下し始めます。後続のパフォーマンスヒットが許容できない場合、EFは使用するツールではありません。

したがって、私の質問は、CRUDをefで処理するだけでよいのか、それともストアドプロシージャの代わりとしてEFでもっと多くのことを行うべきなのかということです。

多くのことのように、それはあなたが必要とするものに依存します。

単純なCRUD操作の場合、EFは使用に適したツールです。これにより、多くのboilerplated処理ロジックが不要になります。

単純なデータクエリしかない場合、またはパフォーマンスの最適化を気にしない場合は、いずれにしてもCRUDにEFを既に使用しているので、それらにEFを使用できます。

ただし、複雑なデータクエリがあり、パフォーマンスの最適化に関心がある場合は、EFを使用する必要はありません。私たちのリードアーキテクト(以前はDBAであり、DBのパフォーマンスに非常に関心がありました)は現在、特にワークロードの一部に特化しているため、EFとDapperを同時に使用することを提唱しています。彼は最初はDapperのみを使用することを提案しましたが、EFを使用したCRUDの使いやすさを認め、CRUDの多いアプリケーションでの使用を受け入れています。

しかし、これも主観的なものです。 1つのツールに固執し、欠点を吸収することをお勧めします(たとえば、EFを使用して低速で複雑なクエリを処理するか、またはDapperを使用してボイラープレートCRUDコードを記述する必要に対処します)。または、さまざまなツールを使用して、常にパフォーマンスを絞り込めるようにすることもできます。

2
Flater

いつものように、状況によります。ストアドプロシージャ、ビュー、インデックス、トリガー(など)はDBAにとって優れたツールであり、(リレーショナル)データベース自体が一貫性を保証し、適切なアクセス許可を確保し、可能な限り実行することを確認します。

ただし、これらのツールは、システム全体がデータベースを中心に展開するデータベース中心の設計に向けた確かな道です。つまり、すべてのコードが物理データベースモデルに適応する必要があります。データベースで使用されるデータ型は、メモリ内の型などを決定します。これは、リカクタリングに書き換え(およびテスト/デバッグ)が含まれている場合、ビジネスロジックコードからデータベースレイヤーのリファクタリングを開始することが非常に難しいためです。ストアドプロシージャ、トリガー、カスタムSQLコード。

EF(および同様のツール)の主な利点は、単純なCRUDコンポーネントの開発を容易にすること(IMHO)ではありませんが、それらのコンポーネントのその後のリファクタリングがはるかに容易になることです。 (あなたがコードファーストを行うと仮定して)

はい、複雑な結合を開始すると、パフォーマンスコストが発生します。 EFへの素朴なアプローチがある場合、その価格ははるかに高くなります。

ただし

複雑な結合が含まれている可能性があるSQLクエリが原因で実際​​の(エンドユーザーが実際に苦しんでいるような)パフォーマンスの問題に遭遇した場合、ストアドプロシージャはバンドエイドです。

データの整合性またはクエリのパフォーマンスのためにストレージを最適化できますが、両方はできません。両方が必要な場合は、CQRSまたは同様のパターンを調べてください。

TL; DR

  • EFを使用すると、データアクセスコードの記述とリファクタリングが高速化されます。
  • これの代償は最適ではないクエリです(EFの経験がない場合はさらに悪くなります)。
  • ストアドプロシージャやその他のDBAテクニックを使用すると、DBのパフォーマンスを向上させることができます。
  • この代償として、ビジネスコードの記述とリファクタリングが難しくなります。
  • クエリのパフォーマンスが問題となる場合(EFを適切に使用できる場合)、SQLを最適化するのではなく、設計全体を再評価してください。
2
Guran

@Guranの回答に追加するだけです。EFの経験は特にありませんが、ORMを使用しているときに、結合や負荷の高い操作を扱っていることを忘れがちです。したがって、モデルインスタンスを通常の変数として扱い、それらを複雑な操作に含めることで、おそらくさらに複雑なSQLクエリに変換されます。データベースサーバーでより効率的に実行できるループと集計を使用したクライアント側のコードも見ました。

そのため、sql/storesプロシージャを手動で作成すると、パフォーマンスへの影響についてより意識するようになります。

1
sul4bh

いくつかの要件でsprocが必要なほとんどの場合。将来のビジネスルールのリファクタリングが必要になった場合に実行するSQLスクリプトファイルをコードベースに配置します。私は、ほとんどの新しい開発者と経験豊富な開発者がdbmsでの作業にある程度の経験があると思います。 DB sprocの要件を知る必要がある人は、必要に応じてスクリプトを確認および更新できます。ビジネスルールとDBの要件は、ソースコードファイルにあります。ほとんどの複雑なソリューションには一方向の方法はないと信じています。 (JMO)。

0
Glh