私は同じ種類のもの、たくさんの列、そして1000の異なる選択方法で動作しているテーブルを持っています。その悪夢。ただし、頻繁に使用されるフィルターの特定の組み合わせがあります。インデックスを作成し、実行速度が遅くなることはめったにない他のインデックスを残すものです。 MSSQLでは、クエリを実行して、データベースに対して実行された最もコストのかかるクエリを表示できます。mySQLにも同様の機能が必要です。それらを取得したら、列をカバーするインデックスを作成して、列を高速化します。最終的には、90%がカバーされます。 AK47を指ささない限り、私は個人的にそのようなテーブルを二度とデザインすることはありませんでした。 (私のインデックスはテーブルのデータの3倍であり、束やレコードを追加する必要がある場合は非常にクールではありません)テーブルをどのように再設計するかはわかりませんが、最初に考えたのはテーブルを2つに分割することです、しかしそれは他の場所での頭痛の種になります。
ユーザーテーブル(ユーザーID、名前)
1, Lisa
2, Jane
3, John
ユーザー属性テーブル(UserID、AttributeName、AttributeValue)
1, EYES, Brown
1, GENDER, Female
2, EYES, Blue
2, GENDER, Female
3 EYES, Blue
3, GENDER, Male
これにより、属性の識別が速くなりますが、クエリの記述はそれほど簡単ではなくなります。
SELECT UserID, COUNT(*) as MatchingAttributes
FROM UserAttributes
WHERE (UserAttributes.AttributeName = 'EYES' AND UserAttributes.AttributeValue = 'Blue') OR
(UserAttributes.AttributeName = 'GENDER' AND UserAttributes.AttributeValue = 'Female')
これにより、次のようになります
UserID, MatchingAttributes
1, 1
2, 2
3, 1
次に行う必要があるのは、HAVING COUNT(*)=2をクエリに追加して、一致するIDのみを選択することです。選択するのは少し複雑ですが、優れた機能も提供します。たとえば、10個の属性でフィルタリングし、10個の属性が一致するものをすべて返します。かっこいいですが、100%一致するものはないと言います。ねえと言うことができます、私は一致するものを見つけませんでした、しかしこれらは10のうち9または90%の一致を持っていました。 (青い目のブロンドの女性を検索しても、どこにも見つからないというメッセージは表示されませんが、一致スコアが60%の青い目のブロンドのブロークを含む次に近い一致するものがあります。非常に冷静になる)
テーブルを分割することを選択した場合、属性を数値、日付、テキストとして1つの列にどのように格納するかなど、考慮が必要なことが他にもあります。または、これらの個別のテーブルまたは列です。幅の広いテーブルでも分割テーブルでも簡単な答えはありません。