1
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 行以上が追加されます。私のウェブサイトは急速に成長し続けています。

なぜこんなに列が多いのか聞かないでください。彼らはオンライン対戦でゲームをプレイし、それらの列はプレイヤー同士の対戦です。

4

5 に答える 5

2

私もTable2に行きます。

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

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

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

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

Table2 の計画は明らかにもっと単純です。

于 2010-02-09T22:50:33.997 に答える
1

私ならTable2を選びます。

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

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

ただし、インデックスの少なくとも 1 つがクラスター化されておらず、プレイヤーに関連するすべてのアイテムを識別するために多くのロジック ジャグリングが必要になります。そして、将来的に 3 方向のゲームがもたらす混乱について考えてみてください (3 人のプレーヤー、IdColumn3 を追加...)。

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

ただし、PairId が何であるかはわかりません。データ モデルは典型的な多対多の関係です。'Player' を 'Student' に、'Game' を 'Course' に置き換えるだけで、Students-Course の正規のデータ モデリング 101 コース構造が正確に得られることがわかります。 (あなたの場合、ゲーム(=コース)に正確に2人のプレーヤー(=学生)がいる可能性がありますが、それは詳細です。あなたはまだ典型的な3つのテーブルの関係について話している(ゲーム用に1つ、プレーヤー用に1つ、プレイヤーからゲームへの参加の場合)。

于 2010-02-09T22:27:59.643 に答える
1

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

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

これは、全体として、EAV モデルは、特に 100 万を超えるエンティティ (つまり、おそらくいくつかの各エンティティに多くの属性がある場合、数十万の EAV エントリ)。
実際、この点を証明するために、いくつかの EAV 実装では両方のモデルの混合が導入されています。これにより、ほとんどのエンティティに共通の単一値の属性が、EAV リストではなく「ヘッダー ファイル」に格納されます。

もちろん、2 つのモデルのどちらがより効率的かという最終的な言葉は [OR-ed 列値の問題の制限的なコンテキストで]、効果的な実装、インデックス、およびデータの統計プロファイルに依存します。 小さい EAV テーブル (約 500,000 エントリのこのテーブルのような) の場合、EAV モデルはおそらく一般的なケースで優位性を提供します

この関連する SO 記事: database: EAV pros,cons and alternatives を参照してください。一般に、いくつかの SO 記事を eav タグでスキャンしてください。

于 2010-02-09T22:34:00.500 に答える
0

言うのは難しいです。idColumn は主キーであるため、両方のパフォーマンスが似ているか、2 番目の方が優れているはずです。クエリの実行計画を確認し、適切なインデックスがあることを確認してください。

于 2010-02-09T22:23:36.380 に答える
0

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

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

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

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

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

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

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

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

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

于 2010-02-09T22:24:03.757 に答える