0

現在、SqlDataReader とストアド プロシージャを使用して C# で DAL を手書きしています。パフォーマンスは重要ですが、それでも維持できるはずです...

テーブルレシピがあるとしましょう

(recipeID, author, timeNeeded, yummyFactor, ...)

そして食卓の食材

(recipeID, name, amount, yummyContributionFactor, ...)

ここで、200 ほどのレシピとその材料をクエリしたいと思います。次の可能性が見えます。

  • すべてのレシピをクエリしてから、各レシピの材料をクエリします。
    もちろん、これは maaany クエリになります。
  • 結合された大きなリストですべてのレシピその材料を照会します。これにより、すべてのレシピ データが複数回送信されるため、多くの無駄なトラフィックが発生します。
  • すべてのレシピをクエリしてから、レシピ ID のリストをデータベースに戻して、すべての材料を一度にクエリします。または、両方のクエリを一度に発行して、複数の結果セットを返します。DAL に戻り、recipeID によって材料をレシピに関連付けます。
  • エキゾチックな方法: すべてのレシピをカーソルで移動し、各レシピについて、レシピと材料の 2 つの個別の結果セットを返します。結果セットに制限はありますか?

多様性を高めるために、DAL からの ID のリストまたはパラメータ化された SQL 条件によってレシピを選択できます。

パフォーマンスと混乱の比率が最も高いのはどれだと思いますか?

4

5 に答える 5

2

最高のパフォーマンス/混乱率は 42 です。

より深刻なことに、最も単純な解決策を採用してください。単一のクエリですべてを取得します。パフォーマンスの問題が発生する前に最適化しないでください。「時期尚早の最適化は諸悪の根源です」:)

于 2010-02-07T18:16:58.883 に答える
2

2 つのテーブルを結合するだけで、「成分」が大量のデータではない場合、パフォーマンスと保守性の最適なバランスは、単一の結合クエリである可能性があります。はい、結果でいくつかのデータを繰り返していますが、100,000 行があり、データベース サーバー/ネットワークに過負荷がかかっていない限り、最適化するには時期尚早です。

それぞれカーディナリティが減少する多数の結合レイヤーがある場合、話は少し異なります。たとえば、私のアプリの 1 つで、次のようなものがあります。

Event -> EventType -> EventCategory
                   -> EventPriority
                   -> EventSource   -> EventSourceType -> Vendor

このようなクエリの結果、取得するイベントが 10 万件、イベント タイプが 1000、カテゴリ/優先度が 10、ソースが 50、ベンダーが 5 の場合、許容できないほどの重複が発生します。その場合、複数の結果セットを返すストアド プロシージャがあります。

  • EventTypeID のみの 100k イベントすべて
  • これらのイベントに適用される CategoryID、PriorityID などを持つ 1000 の EventTypes
  • 上記の EventTypes に適用される 10 個の EventCategories と EventPriorities
  • 100k イベントを生成した 50 個の EventSource
  • などなど、お分かりですね。

カーディナリティが大幅に低下するため、ここで必要なものだけをダウンロードし、クライアント側でいくつかの辞書を使用してそれらをつなぎ合わせる方がはるかに高速です (必要な場合でも)。場合によっては、カーディナリティの低いデータがメモリにキャッシュされ、データベースからまったく取得されないことがあります (アプリの起動時またはデータの変更時を除く)。

このようなアプローチを使用する際の決定要因は、結果の数が非常に多いことと、結合のカーディナリティが急激に低下すること、つまりファニング インです。これは実際にはほとんどの使用方法の逆であり、おそらくここで行っていることの逆です。「レシピ」を選択して「材料」に結合している場合、特に結合するテーブルが 2 つしかない場合は、このアプローチが無駄になる可能性があります

したがって、パフォーマンスが今後問題になる場合、これが可能な代替手段であることを示しています。設計のこの時点では、実際のパフォーマンス データを取得する前に、結合された 1 つの結果セットを使用する方法に進みます。

于 2010-02-07T18:38:23.177 に答える
0

「レシピヘッダー」と「レシピ詳細」の2つのデータセットを返す1つのストアドプロシージャ?

これは、一度にすべてのデータが必要な場合に行うことです。一度に必要ない場合でも、2 つのデータセットを取得できますが、データは少なくなります。

Andomar が提案した 1 つの大きなクエリよりも、クライアントでこれを処理する方が少し簡単であることがわかりましたが、彼/彼女の答えは依然として非常に有効です。

于 2010-02-07T18:31:30.197 に答える