SQL サーバー 2005:どちらが速いですか?2 列以上の条件を設定しますか? それとも 2 行以上の条件を設定しますか?

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

質問

Table1
------------
ID
IdColumn1
Idcolumn2

Table2
------------
ID
IdColumn
IdPair

どちらにも同じデータが含まれています。

Table1 には両方の列が設定されており、Table2 にはそれらの列が 2 つの行に格納されています。

したがって、Table1 に n 行が含まれる場合、Table2 には 2 * n 行が含まれます。

どちらのクエリが速いですか?

select * from Table1 
where IdColumn1 = x or IdColumn2 = x

または

select * from Table2 where IdColumn = x

私はすでに Table2 スキームを選択しており、これまでに 400,000 行を超え、1 日あたり 1000 人を超えるユニーク訪問者がいます。このデータベースには毎日 2000 行を超える行が追加されます。私のウェブサイトは非常に急速に成長し続けています。

なぜこんなに多くの列があるのか​​は聞かないでください。彼らはオンライン大会でゲームをプレイしており、それらの列はプレイヤー間の試合です。

役に立ちましたか?

解決

私なら Table2 を選びます。

Table1 スキーマでは、少なくとも 2 つのインデックス (IdColumn1 に 1 つと IdColumn2 に 1 つ) が必要で、次を使用して効率的にクエリできます。

select * from Table1 where IdColumn1 = x
union all 
select * from Table1 where IdColumn2 = x;

ただし、インデックスの少なくとも 1 つは非クラスター化されており、プレイヤーに関連するすべてのアイテムを識別するには、多くのロジックをやりくりする必要があります。これらのアイテムは IdColumn1 または IdColumn2 のいずれかに存在する可能性があるためです。そして、将来 3 ウェイ ゲーム (3 人のプレーヤー、IdColumn3 の追加...) がもたらされることを考えてください。

Table2 には明確な目的があるため、より優れています。プレーヤーが参加したすべてのゲームをプレーヤー ID ごとにクラスター化して保存します。より簡単に調査でき、よりシンプルに構造化でき、後でゲームごとにより多くのプレイヤーに拡張できます。

ただし、PairIdが何であるかはわかりません。データ モデルは典型的な多対多の関係です。「プレーヤー」を「学生」に、「ゲーム」を「コース」に置き換えるだけで、学生 - コースの正規のデータ モデリング 101 コース構造とまったく同じであることがわかります。 (あなたの場合、ゲーム (= コース) にはちょうど 2 人のプレイヤー (= 生徒) が参加できますが、それは詳細です。あなたはまだ典型的な 3 つのテーブル関係 (ゲーム用に 1 つ、プレーヤー用に 1 つ、プレーヤー間の参加用に 1 つ) について話しています。

他のヒント

私なら Table2 も使います。

アプローチの違いを強調するために、Table1 には IdColumn1 と IdColumn2 に非クラスター化インデックスがあり、Table2 には IdColumn に非クラスター化インデックスがあると仮定して、オプションに対して生成された 3 つの実行プランを次に示します。ID はクラスター化されています。テーブル 1 に 100,000 レコード、テーブル 2 に 200,000 レコード

1) 2 つの ID 列に対する OR 条件を使用した Table1 アプローチ:
代替テキスト http://img52.imageshack.us/img52/3264/23430147.png

2) 2 つのステートメントと UNION ALL を組み合わせた Table1 アプローチ:
代替テキスト http://img192.imageshack.us/img192/6281/47968640.png

3) 表 2 のアプローチ:
代替テキスト http://img52.imageshack.us/img52/2131/72286216.png

Table2 の計画は明らかにはるかに単純です。

表 2 は、 エンティティの属性値 モデル (EAV) は、このモデルが従来のテーブル モデル (およびリレーショナル モデル全体) に比べていくつかの利点を提供するため、よく選択されます。EAV の既知の利点の 1 つは、複数の列の値に基づく OR 検索が効率的であり、従来のモデルでのコーディングが容易であることです。

また、新しい SQL サーバー実装によって提供されるいくつかの新機能は、EAV モデルに役立ちます。

これは全体的に言って、 EAV モデルは、パフォーマンスよりも、論理スキーマに関してもたらす柔軟性やその他の関連する利点により魅力的です。, 特に、100 万を超えるエンティティを含むデータベースに適用される場合 (つまり、各エンティティが多くの属性を持つ場合、おそらく数十百万の EAV エントリになります)。
実際、この点を証明するように、いくつかの EAV 実装では両方のモデルの混合が導入されており、これにより、ほとんどのエンティティに共通する単一値の属性が EAV リストではなく「ヘッダー ファイル」に格納されます。

もちろん、最終的に 2 つのモデルのどちらが (OR 演算された列値の問題という制限された状況において) より効率的であるかは、効果的な実装、インデックス、およびデータの統計プロファイルによって決まります。 小さい EAV テーブルの場合 (c.500,000 エントリ)、一般的なケースでは、EAV モデルがおそらく優位性を提供します。.

この関連する SO 記事を参照してください。 データベース:EAV の長所、短所、および代替案そして一般的には、 eav タグを含む SO 記事はほとんどありません.

言うのは難しいです。idColumn が主キーであるため、どちらも同様のパフォーマンスになるか、おそらく 2 番目の方が優れているはずだと思います。クエリ実行プランをチェックし、適切なインデックスがあることを確認してください。

一方のテーブルが他方のテーブルより高速になる唯一の原因は、テーブルにどのようなインデックスを作成するかです。最初のテーブルに正しいインデックスを作成しない限り (またはその逆)、2 番目のテーブルを使用してもパフォーマンス上の利点はありません。

たとえば、テーブル 1 の idcolumn1 とテーブル 2 の idcolumn にインデックスを作成したため、2 番目のテーブルの方が高速であるように見えるかもしれません。代わりに、テーブル 1 の idcolumn1 にインデックスを作成し、idcolumn2 に別のインデックスを作成した場合は、非常に似たパフォーマンスが得られます。

テーブル 2 はデータの重複であるため、このテーブルを維持することはお勧めできません。すべての更新では 2 つの行を変更する必要があります。

ただし、このタイプのデータのデータ設計は次のようになっていることがあります。

match table
-----------
matchid
additional match information

participants table
------------------
participantid
matchid

このスキーマでは、一致テーブルに各一致 (および追加データ) ごとに 1 つの行があり、テーブル 2 と似たテーブルができます。参加者を試合に関連付けます。

次に、参加者を選択し、それを試合データにリンクするだけです。

これがあなたの状況にとってベストプラクティスになると思います。

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