質問

私は次の表を持っています:

Matches -> match_id, team_a_id , team_b_id, score
.

このテーブルは2つのチーム(チームAとチームB)の間で一致を記録します。ただし、ホストとしてチームAが遊びになることがあり、チームBがホストとして再生されます。したがって、私がチームAとチームBの間の歴史の一致を見つけようとしたとき私が現在やっていることは

select * from matches where (team_a_id = 1 and team_b_id = 2) or (team_a_id = 2 and team_b_id = 1);
.

そのような場合にはより良いアプローチはありますか?上記のクエリに関しては、Team_A_IDとTeam_B_IDの組み合わせのインデックスを含める権利ですか?しかし、そうであっても、私はまだabまたはbaの間の論理的または状態を持っています。

あるいは、 私は別のアイデアを持っています、それは別のテーブルを持っていることです

History -> team_hash, match_id
.

私は手動でteam_hashを構築し、ここでhash(a,b) == hash(b,a)。しかし、この結果はわずかに遅い挿入で、より速い読み取りです。それとも本当に速い読み方ですか?

役に立ちましたか?

解決

{team_a_id, team_b_id}に合成インデックスがあると仮定すると、DBMSは2つのインデックスシーク(team_a_id = 1 and team_b_id = 2用の1つとteam_a_id = 2 and team_b_id = 1の場合はもう1つ)を使用してSQLステートメントを実行できます。私はあなたが欠けているパフォーマンスを見つけることを期待していません。


しかし、これらのインデックスシークのいずれかを排除する方法があります。制約を追加してください...

CHECK(team_a_id < team_b_id)
. 必要に応じて、「方向」(すなわちどのチームがホストである)を別のフィールドにエンコードします。このようにして、team_a_id = 2 and team_b_id = 1がTrueになることができないことがわかりますので、team_a_id = 1 and team_b_id = 2を検索するだけです。


「対称的な」ハッシュはきちんとした考えですが、:

  • ハッシュの正当性を宣言的に実施することはできません - トリガーまたはアプリケーションレベルで実行する必要があります。
  • それは冗長なデータです。ハッシュ競合を解決するために、team_a_idteam_b_idを維持する必要があります。より大きなデータは効果的に小さいキャッシュを意味します。
  • 実際にインデックス数を増やす可能性があります - 基準整合性の効率的な執行はおそらく、実際のSQLクエリに必要な場合でも、team_a_idおよびteam_b_idの索引を必要とします。キャッシュに圧力を増すことに加えて、挿入/更新/削除パフォーマンスを潜在的に傷つける可能性があるすべての追加インデックスを維持する必要があります。状況は、クラスタリングをオフにすることができないINOOODBでは特に深刻です。 ovaistariq.net/521/UnderStanding-innodb-clustered-indexes/ "rel=" nofollow ">この記事)。

他のヒント

あなたはこの

のようなものをどこでもすることもできます。
((team_a_id = 1 and team_b_id = 2) or (team_a_id = 2 and team_b_id = 1))
AND team_a_id IN (1,2) AND team_b_id IN (1,2)
.

このように、(Team_a_ID、Team_B_ID)のようなインデックスを使用することが可能です。

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