プロジェクトのシナリオ:
最近はパフォーマンスの最適化や全文インデックスの利用、レコードの作成などを行っています。
問題の説明
リスト クエリを実行するとき、ほとんどの場合、「%%」のようなクエリが発生し、この種のクエリはインデックスを無効にします。データ量が多いと、クエリが非常に遅くなります
。もちろん、 es を使用して最適化することもできますが、es を導入すると、使用しない場合よりもコードが複雑になるため、必要がない場合は mysql を直接使用します。
解決:
1. mysql の全文インデックスの制限により、mysql バージョン 5.7 以降でサポートされている必要があります。バージョンがわからない場合は、コマンドを使用してバージョン番号を確認してください。
select version();
次に、次のようにインデックス SQL を作成します。
CREATE FULLTEXT INDEX idx_fullname ON t_course(name) WITH PARSER ngram;
CREATE FULLTEXT INDEX idx_fullname ON t_course_type(name) WITH PARSER ngram;
ここでは WITH PARSER を使用する必要があります。 ngram は中国語の単語の分割に適しています。検索対象のコンテンツが英語の場合は、次の段落を追加する必要はありません。
3. mysql 設定を次のように変更します
。mysql インストール ディレクトリで、設定ファイル D:\javaTools\mysql-8.0.12-winx64\my.ini を見つけます。ない場合は、自分で新しい設定ファイルを作成します。次の構成を追加します
innodb_ft_min_token_size = 1 #配置分词最小单位
ft_min_word_len = 1 #配置分词最小单位
変更を有効にするには再起動が必要です。
これら 2 つの設定を追加する理由は、粒度を最小限に分割するためです。そうでない場合は、「Hello」を検索しても、コンテンツにこれら 2 つの単語が含まれていますが、検索することはできません。これら 2 つの値のデフォルト値は、は4です。それで修正してください。
再起動後、コマンドを使用して設定が有効かどうかを確認します
show variables like '%ft%';
4 番目に、全文インデックス検索を使用します。
select
tc.id,
tc.name
from
t_course tc
where
match(name) against ('测试') limit 5
テストに関連するコンテンツが検出されたことがわかり、インデックスされているかどうかを確認するために説明します。
全文インデックスが残っていることがわかります。
5. 複数フィールドの全文インデックス
CREATE FULLTEXT INDEX idx_fullname ON t_course(name,字段名) WITH PARSER ngram;
match(name,字段名) against ('测试')
上記のように複合インデックスを構築するだけです。
6. 結合して 2 つのテーブルのフルテキスト インデックスをクエリします。
両方のテーブルにフルテキスト インデックスが必要なフィールドがある結合クエリのケースがあります。テスト後、この状況は機能しません。同様に、coursetype テーブルの名前フィールドにもフルテキスト インデックスがあります。
explain select
tc.id,
tc.name,
tct.name,
tct.id
from
t_course tc left join t_course_type tct on tc.course_type =tct.id
where
1=1
and (
match(tc.name) against ('测试')
or match(tct.name) against ('测试')
)
こうすることでインデックスは検索されず、コース名と種類名も同時にあいまい検索されます。この種の状況は別の方法でしか解決できません。
(a left join b where match(a.name) ) union (a right join b math(b.name))
これを達成するためにこの方法を使用することを検討できますが、SQL の複雑さが大幅に増加します。実際、このように使用することはお勧めできません。直接。
要約する
この記事では全文インデックスの使い方を紹介しますが、注意点などは上に書いた通りですので、実際の活用プランを皆さんに向けてまとめておきますので、必要な方は参考にしてみてください。