2

2 つのテーブルを結合するか、2 つの個別のクエリを使用するかの二分法について簡単な質問があります。

既存の質問を見つけたいと思っていましたが、検索してもあまりヒットしませんでした (ほとんどの質問はより複雑な問題に関するものでした)。

たとえば、非常に単純なスキーマを持つ 2 つのテーブル A と X があるとします。

Table A   +-------------+-------------+-------------+
          | Column A (*)| Column X(FK)| Column C    |
          +-------------+-------------+-------------+

Table X   +-------------+-------------+-------------+
          | Column X (*)| Column Y    | Column Z    |
          +-------------+-------------+-------------+

列 A と X は ID 列と主キー (bigint) です。テーブル A と X の間には、列 X の既存の外部キー関係もあります。

私の質問は、両方のテーブルが十分に大きい (たとえば 500K 行) と仮定すると、単一のクエリを使用することでパフォーマンスの点でより多くのメリットが得られるでしょうか (以下の Linq2Sql 擬似コードを参照)、または 2 つの別個のクエリを使用することでしょうか?

オプション1:

long aValue = 107;
DataContext dc = new DataContext();
var items = (from a in dc.TableA
             join x in dc.TableX
             on a.X equals x.X
             where a.A == aValue
             select new { a, x });

オプション 2:

  • 2 つの個別の select ステートメントを連続して実行する SP を作成するとします。

問題をさらに定量化するために、A のすべての値に対して、テーブル Y から結合される行はわずか (0 ~ 5) であるため、結合で返されるテーブル A のデータの重複は重要ではないと仮定できます。

DBサーバーへの影響の観点から厳密にお願いしています。したがって、クライアント側の考慮事項 (ラウンドトリップ ネットワークの遅延、L2S クエリの構築、データ マーシャリングのコストなど) を無視すると、私の質問は次のとおりです。

  1. DB サーバーでの計算に時間がかからないオプションはどれですか?

  2. 結果を評価するために必要なメモリが少ないオプションはどれですか?

  3. ベスト プラクティスがある場合、どのオプションが一般的に好まれますか?

これが初歩的すぎるように聞こえる場合は申し訳ありませんが、洞察をいただければ幸いです。

ありがとう - K.

4

2 に答える 2

2

簡単な答え: オプティマイザーを信頼してください。

適切にインデックス付けされたテーブルに対する単一のクエリ (特に単純な結合による) は、一連のシリアル SQL ステートメントを記述するよりも効率的です。私は LINQ の専門家ではないので、疑似コードでどの列が返されるかはわかりませんが、適切なハードウェアでテーブルが適切にインデックス付けされていれば問題ありません。

于 2012-11-16T23:39:45.723 に答える
1

忙しいデータベースでの私の経験から、結合を使用して 1 つのクエリを実行するよりも、結合を使用せずに 2 つのクエリを実行する方が常に優れています。

これら 2 つのアプローチには常に 1 つの違いがあります。結合する場合、SQLは何らかの方法で行を一致させる必要があります (返されると予測される行数が少ない場合は、おそらくネストされたループを使用します)。ワークロードまたは結果セットが大きい場合、それが問題になり始めます。

データベースがボトルネックになることが予想されず、この結合によって開発が何らかの形で簡素化される場合は、先に進んでください。


より大きなテーブルで数値を提供するために、私が管理する DB の親テーブルと子テーブルに対して 2 つのアプローチを試みました。それぞれ15万行と300万行あります。SQL はこれらの統計を出力します。

結合クエリ

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 7 ms.
Table 'child'. Scan count 1, logical reads 324, physical reads 0, read-ahead reads 0.
Table 'parent'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0.

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 70 ms.

別々の選択

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
Table 'parent'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0.

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(1 row(s) affected)
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
Table 'child'. Scan count 1, logical reads 324, physical reads 0, read-ahead reads 0.

SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 1 ms.

(テーブルには適切なインデックスが配置されています。テーブル名は変更されています)

于 2012-11-16T23:58:07.027 に答える