メインコンテンツへスキップ

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
MySQL の LIKE '%keyword%' は小さなテーブルでは機能しますが、インデックスを使えません。すべての行がスキャンされます。全文検索は、テキスト列を検索するための、インデックスを使った順位付きの代替手段を提供します。

FULLTEXT インデックスの作成

FULLTEXT インデックスは、InnoDB(デフォルトのストレージエンジン)と MyISAM のテーブルの CHAR、VARCHAR、および TEXT 列で機能します。
既存のテーブルに FULLTEXT インデックスを追加します。
1 つの 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 条件と通常どおり組み合わせます。
MySQL は全文検索の部分に FULLTEXT インデックスを使い、他のインデックス付きの列でのフィルタは別に行えます。

MySQL の全文検索は複数の言語をサポートしていますか?

MySQL にはいくつかの言語の組み込みストップワードリストがあります。本番環境の多言語検索では、通常、innodb_ft_enable_stopword = OFF を設定して innodb_ft_server_stopword_table で独自のストップワードテーブルを提供するか、外部の検索エンジン(Elasticsearch、MeiliSearch)を使う必要があります。

トラブルシューティング

関連項目