複数の列を持つテーブルがあります。たとえば、a
、b
、c
、d
で、検索可能にする必要があります。問題は、検索する必要があるときに発生しますa, b, c
とは別にd
(およびその逆)。私の知る限り、すべての列で1つの複合フルテキストインデックスを使用してこれを実現する方法はないため、次のように2つの個別のインデックスを作成します。
CREATE FULLTEXT INDEX idx1 ON content (a, b, c);
CREATE FULLTEXT INDEX idx2 ON content (d);
これで、1番目と2番目の検索が成功しました。どちらの場合も、次のコマンドを使用します。
SELECT * FROM content
WHERE MATCH(a, b, c) AGAINST ('keyword')
AND MATCH(d) AGAINST ('keyword');
explain
はこれを教えてくれます:
+----+-------------+---------+----------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+----------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | content | fulltext | idx1,idx2 | idx1 | 0 | | 1 | Using where |
+----+-------------+---------+----------+---------------+------+---------+------+------+-------------+
すごい!したがって、2つのインデックスを使用していますが、keyword
が両方に含まれ、どちらかが必要な行のみを返すため、AND
をOR
に変更して、次のように説明しています。
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | content | ALL | NULL | NULL | NULL | NULL | 128 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
何?突然、それは全表スキャンを行っています。なぜこうなった?これを回避する最良の方法は何でしょうか?
残念ながら、これはMySQL Query OptimizerがFULLTEXTインデックスを処理する方法です。 MATCH
句がWHERE
の唯一の句である場合、インデックスが使用されます。 AND
と組み合わせて使用すると、インデックスが見落とされやすくなります。
私は以前にこの動作について書きました Mysql全文検索my.cnf最適化
提案:2つのFULLTEXT検索の結合としてクエリを書き換えます
SELECT * FROM content
WHERE MATCH(a, b, c) AGAINST ('keyword')
UNION
SELECT * FROM content
WHERE MATCH(d) AGAINST ('keyword');
GIT IT A TRY !!!
何をしたいのか不明確。
keyword
およびa,b,c
のどこかにd
を含む行を表示する場合は、AND
が適しています。
ただし、keyword
をa,b,c,d
のいずれかに含めたい場合は、thirdインデックスを追加します
FULLTEXT(a,b,c,d)
そしてに変更
MATCH(a,b,c,d) AGAINST('keyword')
詳細については、InnoDBまたはMyISAMのどちらを使用しているかを指定してください。それらは異なる働きをします。