0

データベースの特定の部分が大きくなり、パフォーマンスの問題が発生しています。次のようなテーブルがあります。

itemID | name   | value
2      | action | throw
1      | thing  | ball
3      | looks  | dumb
2      | thing  | stick
3      | thing  | rock
1      | action | hit
4      | looks  | grey
1      | action | wedge
3      | action | throw

このテーブルをクエリして、1 つ以上の名前 (AND) を持つ複数の名前の onw と 1 つまたは 1 つ以上の値 (OR) に一致する項目 ID を検索する必要があります。今日まで、私は次のようなORでこれを達成しました:

SELECT t1.id FROM features as t1
    LEFT JOIN features as t2 on t1.id = t2.id
WHERE
(
     (t1.`name` = 'thing' AND t1.`value` LIKE 'ball') 
  OR (t1.`name` = 'thing' AND t1.`value` LIKE 'stick')
) 
AND
(
        t2.`name` = 'action' 
   AND (t2.`value` LIKE 'hit' OR t2.`value` LIKE 'thro%')
)

*この例では、各名前に 2 つの値がありますが、任意の数が存在する可能性があることに注意してください。明確にするのに役立つ場合は、この sqlFiddleがあります。

これはしばらくの間うまくいきましたが、システムが進化するにつれて、これらのテーブルは大きくなり (時には 400 万行を超えることもあります)、さらに問題なのは、これらのテーブルで実行されるクエリに多くの名前/値セットを含める必要があることです。4 番目の JOIN の後、パフォーマンスが劇的に低下し、9 までに、クエリの実行に 1 分以上かかることがあります。また、オプティマイザの深さを 1 に設定してバンドエイドした数時間、STATISTICS ステップでクエリがフリーズするという問題がありましたが、それは理想的とは言えません。

結合をあまり行わずにこのクエリを実行するにはどうすればよいですか?

編集:質問をしたときに要件の1つを逃しました(月曜日の場合)。値列のクエリ値は、大文字と小文字を区別しない必要があり、ワイルドカードも使用できます。それに応じてクエリの例を編集しました。

4

1 に答える 1