VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
LIKE '%keyword%' は小さなテーブルでは機能しますが、インデックスを使えません。すべての行がスキャンされます。全文検索は、テキスト列を検索するための、インデックスを使った順位付きの代替手段を提供します。
FULLTEXT インデックスの作成
FULLTEXT インデックスは、InnoDB(デフォルトのストレージエンジン)と MyISAM のテーブルの CHAR、VARCHAR、および TEXT 列で機能します。
FULLTEXT インデックスを追加します。
FULLTEXT インデックスは複数の列にまたがることができます。そのインデックスに対するクエリは、インデックス化されたすべての列を同時に検索します。
MATCH…AGAINST によるクエリ
全文クエリはMATCH(columns) AGAINST(expression) 構文を使います。MATCH の列リストは、FULLTEXT インデックスの列と正確に一致しなければなりません。
MATCH...AGAINST が WHERE 句にあるとき、MySQL は関連度の降順で行を返します。AGAINST 式は関連度スコアを返し、0 は一致なしを意味します。
検索モード
MySQL は 3 つの検索モードをサポートしています。自然言語モード
デフォルトです。MySQL は、極端によくある単語を事実上無視する重み付け方式を使います。ほぼすべての行に現れる語は、関連度スコアにほとんど寄与しません。英語のよくあるストップワード(the、is、at)は完全に除外されます。明示的な ORDER BY がない場合、結果は関連度の降順で返されます。
ブールモード
ブールモードは、精密な制御のための演算子をサポートします。
InnoDB テーブルでは、
MATCH() 式のすべての列に FULLTEXT インデックスが必要です。それがないと、InnoDB でのブールモードのクエリはエラーを返します。(MyISAM は FULLTEXT インデックスなしのブールモードを許可しますが、すべての行をスキャンします。)
クエリ拡張
2 パスの検索です。MySQL は最初のクエリを実行し、上位の一致を取り、そこから追加の語を抽出し、それらの語を加えて検索を再実行します。全文検索と LIKE の比較
小さなテーブルでの単純なパターン一致、前方一致検索(インデックス付きの
LIKE 'prefix%')、または任意のパターン一致が必要な場合は LIKE を使います。テキスト列の中の単語やフレーズを検索していて、関連度の順位付けや大規模でのより良いパフォーマンスが必要な場合は、全文検索を使います。
最小の単語長
InnoDB のデフォルトの最小トークンサイズは 3 文字です(innodb_ft_min_token_size)。3 文字より短い単語はインデックス化されません。2 文字の単語のためには、最小値を下げます。
innodb_ft_min_token_size は動的変数ではありません。有効にするにはサーバーの再起動が必要です。再起動後、すべての FULLTEXT インデックスを再構築します。
よくある質問
単語がテーブルにあるのに、MATCH…AGAINST が行を返さないのはなぜですか?
よくある理由は 3 つです。(1) 単語がinnodb_ft_min_token_size(デフォルト 3)より短い。(2) 単語がストップワードリストにある。(3) MyISAM テーブルで、単語が 50% 以上の行に現れる。MyISAM の自然言語モードは、そのような単語を役に立たないほどよくある単語として扱います。InnoDB にはこの制限がありません。MyISAM の 50% のしきい値を回避するにはブールモードを使います。
全文検索を WHERE 条件と一緒に使えますか?
はい。MATCH...AGAINST を他の WHERE 条件と通常どおり組み合わせます。
FULLTEXT インデックスを使い、他のインデックス付きの列でのフィルタは別に行えます。
MySQL の全文検索は複数の言語をサポートしていますか?
MySQL にはいくつかの言語の組み込みストップワードリストがあります。本番環境の多言語検索では、通常、innodb_ft_enable_stopword = OFF を設定して innodb_ft_server_stopword_table で独自のストップワードテーブルを提供するか、外部の検索エンジン(Elasticsearch、MeiliSearch)を使う必要があります。
トラブルシューティング
関連項目
- MySQL のインデックスの仕組み — FULLTEXT は B ツリーと並ぶ特殊なインデックスの種類です
- MySQL の JSON — 構造化データと並べて JSON のテキストフィールドを検索する
- 多次元の範囲クエリ — テキスト検索が適さない場合に、複数の数値の次元にわたって検索する
- MySQL の LIKE — 大規模環境では全文インデックスが置き換えるパターン演算子
- MySQL の REGEXP — すべての行を読むパターン一致