このドキュメントでは、PolarDB for MySQL のインメモリ列指向インデックス (IMCI) で全文索引を構築して使用する方法について説明します。列レベルの COMMENT を通じて転置インデックスを設定することで、MATCH...AGAINST 構文または自動的に最適化された LIKE クエリを活用し、ミリ秒レベルのあいまい検索を実現できます。この機能は、IMCI の転置インデックスとタームマッチングメカニズムに基づいています。詳細な原理については、「IMCI の全文検索機能の分析」をご参照ください。
バージョン要件
クラスターのバージョンは、次の要件を満たす必要があります。
MySQL 8.0.1 :マイナーバージョンが 8.0.1.1.52 以降であること。
MySQL 8.0.2 :マイナーバージョンが 8.0.2.2.32 以降であること。
構文
PolarDB IMCI では、テーブルの作成時、または DDL で列の COMMENT を変更する際に、列の COMMENT を指定することで、転置インデックスを作成、変更、または削除できます。
構文
テーブルの作成時にフルテキストインデックスを定義します:
CREATE TABLE table_name ( column_name Data_Type COMMENT "imci_fts(type=VALUE [,KEY=VALUE])" ) COMMENT 'columnar=1';ALTERを使用して列を変更し、インデックスを追加または変更します:ALTER TABLE table_name MODIFY column_name Data_Type COMMENT "imci_fts(type=VALUE [,KEY=VALUE])";重要COMMENTを変更すると、転置インデックスの再構築がトリガーされる場合があります。大規模なテーブルの場合、この操作はオフピーク時間に実行することを推奨します。ALTERを使用して列を変更し、インデックスを削除します:ALTER TABLE table_name MODIFY column_name Data_Type COMMENT 'imci_fts(enable=0)';
パラメーター
IMCI 列ストアテーブルを作成するには、テーブルレベルで COMMENT を 'columnar=1' に設定する必要があります。フルテキストインデックスは、列の COMMENT に imci_fts(TYPE=VALUE[, KEY=VALUE]...) の形式で設定します。ここで、TYPE は必須で、KEY はオプションです。複数の KEY ペアはカンマで区切ります。
トークナイザーのタイプ (
typeパラメーター):トークナイザー
type値説明
token
0 (デフォルト)
スペースや句読点などの非英数字でテキストを分割します。英語または整形済みテキストに適しています。
ngram
1
テキストを固定長の文字チャンクに分割します (
lenパラメーターで制御)。あらゆる言語のファジーマッチングに適しています。jieba
2
辞書ベースの中国語トークナイザーです。意味的な中国語検索に適しています。
ik
3
もう一つの広く使われている中国語トークナイザーです。
json
4
JSONPath 式を使用して JSON フィールドからコンテンツを抽出し (
exprパラメーターが必要)、インデックスを構築します。whole
5
テキストを分割しません。列全体が 1 つのタームとして扱われます。主に等価クエリ (= や IN など) の高速化に使用されます。
mysql ngram
6
MySQL 互換の ngram トークナイザーです。
設定パラメーター (
KEY-VALUE):パラメーター (KEY)
デフォルト
説明
適用可能なトークナイザータイプ (
type)enable
1
1:転置インデックスを作成します (デフォルト)0:転置インデックスを削除します
すべて
type
0
トークナイザーのタイプを指定します (上記の表を参照)
すべて
len
-
ngramトークナイザーのトークン長。有効範囲:[1, 256)type=1(ngram),type=6(mysql ngram)mode
0
トークナイザーモード:
jieba (
type=2):0:正確モード (デフォルト)1:フルモード2:検索エンジンモード
ik (
type=3):0:スマートモード (デフォルト)1:最も細かい粒度のモード
json (
type=4):0:レガシー配列モード (デフォルト)1:配列モード2:キーバリューモード ("*.id"、"[*].id"など)
type=2, 3, 4score
0
ソートをサポートするかどうか:
0:ターム頻度 (TF) とドキュメント頻度 (DF) の生成を無効にし、ソートを無視します (デフォルト)1:MATCH ... AGAINSTの関連度スコアによるソートを有効にします
すべて
seg_size
0
転置インデックスのセグメントサイズを指定します:
0:システム変数imci_fts_build_segment_sizeの値を使用しますその他の値:正確なセグメントサイズを指定します
すべて
pack_cnt_min
0
転置インデックス構築のためのデータユニットの最小数:
0:システム変数imci_fts_build_packcnt_minの値を使用しますその他の値:正確な値を指定します
すべて
pack_cnt_max
0
転置インデックス構築のためのデータユニットの最大数:
0:システム変数imci_fts_build_packcnt_maxの値を使用しますその他の値:正確な値を指定します
すべて
stop_word
0
ストップワードをサポートするかどうか:
0:サポートしない (デフォルト)1:サポートする
すべて
case_sensitive
0
マッチングがケースセンシティブかどうか:
0:ケースセンシティブではない (デフォルト)1:ケースセンシティブである2:列のcollate設定によって決定されます (MySQL 互換モード)3:列のcollate設定によって完全に決定されます (collateによって完全に制御)
すべて
phrase
0
フレーズクエリのために位置情報を記録するかどうか:
0:位置情報を記録しない (デフォルト)1:位置情報を記録する
すべて
synonym
0
シノニムをサポートするかどうか:
0:サポートしない (デフォルト)1:サポートする、クエリモード2:サポートする、インデックスモード (転置インデックスの再構築が必要)
すべて
例
1. フルテキストインデックスの作成
テキスト検索が必要な列にフルテキストインデックスを作成し、ビジネスニーズに基づいてトークナイザーを選択します。
テストテーブルの作成:カラムストアインデックスを持つテーブルを作成します。
CREATE TABLE t1 ( id INT PRIMARY KEY, title VARCHAR(32) COMMENT "imci_fts(type=2)" )CHARSET utf8mb4 COMMENT 'columnar=1';(オプション) フルテキストインデックスの変更:
ALTER TABLE文を使用してtitle列にフルテキストインデックスを追加し、Jiebaトークナイザーの検索エンジンモードを指定します。ALTER TABLE t1 MODIFY title VARCHAR(32) COMMENT "imci_fts(type=2,mode=0)";(オプション) トークン化結果の確認:トークナイザーを選択する前に、
dbms_imci.fts_tokenize関数を使用して、さまざまなトークナイザーがテキストをどのように処理するかをプレビューできます。CALL dbms_imci.fts_tokenize("I am PolarDB"); -- 結果:["i", "am", "polardb"] CALL dbms_imci.fts_tokenize("I am PolarDB", "type=1"); -- 結果:["i ", " a", "am", "m ", " p", "po", "ol", "ar", "rd", "db"] CALL dbms_imci.fts_tokenize("I am PolarDB", "type=2"); -- 結果:["PolarDB"] CALL dbms_imci.fts_tokenize("I am PolarDB", "type=2,mode=1"); -- 結果:["polardb"]
2. 全文検索クエリの実行
インデックスが作成されると、IMCI はバックグラウンドでインデックスを構築します。構築が完了すると、MATCH...AGAINST または最適化された LIKE 文を使用してテキストクエリを実行できます。
MATCH...AGAINSTクエリの使用:-- サンプルデータの挿入 INSERT INTO t1 VALUES (16, 'polarDB full-text index feature title'), (17, 'database title performance optimization'); -- title 列に "title" が含まれる行を検索 SELECT * FROM t1 WHERE MATCH(title) AGAINST("title");EXPLAINを使用して実行計画を表示します。FtsTableScanオペレーターが表示された場合、クエリはフルテキストインデックスにヒットしています。EXPLAIN SELECT * FROM t1 WHERE MATCH(title) AGAINST("title") AND id > 10; +----+------------------------+------+-----------------------------------------------------------------+ | ID | Operator | Name | Extra Info | +----+------------------------+------+-----------------------------------------------------------------+ | 1 | Select Statement | | IMCI Execution Plan (max_dop = 32, max_query_mem = 41230008320) | | 2 | └─Compute Scalar | | | | 3 | └─FILTER | | Cond:(t1.id > 10) | | 4 | └─FtsTableScan | t1 | Term:("title") Fallback:(t1.title LIKE "%title%") | +----+------------------------+------+-----------------------------------------------------------------+フォールバックは、まだインデックスが作成されていない増分データがある場合に、結果の完全性を保証するため、システムが自動的にLIKEによる補足スキャンを使用することを示します。LIKEクエリの高速化:既存のアプリケーションコードとの互換性を保つために、IMCI は特定のLIKEクエリを自動的にMATCH...AGAINSTに変換して高速化することをサポートしています。SET imci_convert_like_to_match = on; EXPLAIN SELECT * FROM t1 WHERE title LIKE "%title%"; +----+------------------------+------+-----------------------------------------------------------------+ | ID | Operator | Name | Extra Info | +----+------------------------+------+-----------------------------------------------------------------+ | 1 | Select Statement | | IMCI Execution Plan (max_dop = 32, max_query_mem = 41230008320) | | 2 | └─Compute Scalar | | | | 3 | └─FILTER | | Cond:(t1.title LIKE "%title%") | | 4 | └─FtsTableScan | t1 | Term:("title") Fallback:(t1.title LIKE "%title%") | +----+------------------------+------+-----------------------------------------------------------------+実行計画には
FtsTableScanオペレーターも表示され、LIKEクエリが正常に高速化されたことを確認できます。MATCHからLIKEへの変換:フルテキストインデックスが存在しない場合、IMCI は既存のインデックスを可能な限り活用してクエリを正しく実行するため、MATCHをLIKEに変換することがあります。この場合、実行計画にはフルテーブルスキャンが表示されます。SET imci_enable_query_fts_like = on; EXPLAIN SELECT * FROM t1 WHERE MATCH(title) AGAINST("title"); +----+----------------------+------+-----------------------------------------------------------------+ | ID | Operator | Name | Extra Info | +----+----------------------+------+-----------------------------------------------------------------+ | 1 | Select Statement | | IMCI Execution Plan (max_dop = 32, max_query_mem = 41230008320) | | 2 | └─Compute Scalar | | | | 3 | └─Table Scan | t1 | Cond:(title LIKE "%title%") | +----+----------------------+------+-----------------------------------------------------------------+
3. インデックスの管理と監視
インデックスのビルドステータスとメタデータをクエリし、不要になったインデックスを削除します。
インデックスのビルド進行状況とステータスの監視:
-- すべての転置インデックスを表示 SHOW imci indexes fulltext; SELECT * FROM information_schema.imci_fts_indexes; -- 特定の転置インデックスを表示 SHOW imci indexes fulltext FOR [db_name].[table_name]; SELECT * FROM information_schema.imci_fts_indexes WHERE schema_name='[db_name]' AND table_name='[table_name]'; -- 特定の転置インデックスのメタデータを表示 SELECT * FROM information_schema.imci_fts_index_metas WHERE schema_name='[db_name]' AND table_name='[table_name]' AND column_name='[column_name]'; -- 特定の転置インデックスのセグメントデータを表示 SELECT * FROM information_schema.imci_fts_index_segs WHERE schema_name='[db_name]' AND table_name='[table_name]' AND column_name='[column_name]'; -- 特定の転置インデックスのカラムストアデータを表示 SELECT * FROM information_schema.imci_fts_index_packs WHERE schema_name='[db_name]' AND table_name='[table_name]' AND column_name='[column_name]';フルテキストインデックスの削除:列のフルテキストインデックスが不要になった場合は、列の
COMMENTを変更することで削除できます。ALTER TABLE t1 MODIFY title VARCHAR(255) COMMENT 'imci_fts(enable=0)';
4. 主要なシステム変数
パラメータ | スコープ | 説明 |
imci_enable_fts | グローバル | カラムストアノードで転置インデックスの作成を許可するかどうかを指定します。
|
imci_enable_fts_query | グローバル / セッション | カラムストアノードで転置インデックスの使用を許可するかどうかを指定します。
|
imci_fts_build_pack_cnt_min | グローバル | インデックス構築中の転置インデックスあたりのカラムストアデータブロックの最小数を指定します。 有効範囲:0~8192。デフォルト値:8。値が 0 の場合は、ビルドが一時的に一時停止されます。 |
imci_fts_build_pack_cnt_max | グローバル | インデックス構築中の転置インデックスあたりのカラムストアデータブロックの最大数を指定します。 有効範囲:0~8192。デフォルト値:128。 |
imci_fts_build_segment_size | グローバル | インデックス構築中の各転置インデックスのセグメントサイズを指定します。 有効範囲:0~4294967295。デフォルト値:536870912 (512 MB)、単位はバイト。 |
imci_fts_lru_cache_capacity | グローバル | 転置インデックス辞書のキャッシュスペースを指定します。 有効範囲:[DBNodeClassMemory*1/10~DBNodeClassMemory*1/2]。デフォルト値:[DBNodeClassMemory*10/100]。 |
imci_enable_fts_pruner | グローバル / セッション | 転置インデックスの事前フィルタリング最適化を有効にするかどうかを指定します。
|
imci_convert_like_to_match | グローバル / セッション |
|
imci_enable_query_fts_like | グローバル / セッション |
|
imci_enable_match_expr_fallback | グローバル / セッション | 転置インデックスによってまだインデックスが作成されていない増分データへのクエリを有効にするかどうかを指定します。
|
imci_fts_build_fts_cnt | グローバル | 転置インデックスを構築する同時実行スレッド数を指定します。 有効範囲:0~512。デフォルト値:4。 説明 このパラメータは、次のバージョンにのみ適用されます:
|
imci_fts_user_dict_table | グローバル | フルテキストインデックスのカスタム辞書を設定します。形式: 説明 このパラメータは、次のバージョンにのみ適用されます:
|
imci_fts_user_dict_update | グローバル |
説明 このパラメータは、次のバージョンにのみ適用されます:
|
imci_convert_json_overlap_to_match | グローバル / セッション | JSON インデックスを使用した
|
imci_convert_json_contains_to_match | グローバル / セッション | JSON インデックスを使用した
|
imci_convert_json_extract_to_match | グローバル / セッション | JSON インデックスを使用して
|
imci_convert_equal_to_match | グローバル / セッション | 等価インデックスを使用して
|
imci_convert_in_to_match | グローバル / セッション | 等価インデックスを使用した
|
imci_convert_ne_to_match | グローバル / セッション | 等価インデックスによる
|
imci_enable_fts_synonym | グローバル / セッション | シノニムをサポートするかどうかを指定します。
|
imci_enable_fts_parse_term_with_and | グローバル / セッション | クエリストリングをトークン化した後、
|
imci_enable_fts_parse_term_with_phrase | グローバル / セッション |
|
imci_fts_stop_word_table | グローバル | 全文検索インデックスのカスタムストップワードを設定します。 形式: |
imci_fts_stop_word_update | グローバル |
|
imci_fts_synonym_table | グローバル | 全文検索インデックスのカスタムシノニムを設定します。形式: |
imci_fts_synonym_update | グローバル |
|
GLOBAL スコープのパラメータは、コマンドラインから直接変更することはできません。コンソールからのみ変更できます。コマンドラインから実行した場合、デフォルトのスコープは SESSION になります。
カスタム辞書
IMCI のフルテキストインデックス機能は、カスタムテーブルを通じてカスタム辞書をサポートし、ビジネスシナリオにより適した形態素解析結果を実現します。
カスタム辞書テーブルの作成
まず、
my_fts_dictテーブルと同じ構造を持つテーブルを定義します。列名はmy_fts_dictテーブルの列名と一致する必要があります。type:トークナイザーのタイプ。Jieba トークナイザー (type 2) と IK トークナイザー (type 3) のみをサポートします。
word:辞書の単語。
is_added:カスタム辞書に単語を追加する (値 1) か、削除する (値 2) かを指定します。
CREATE TABLE my_fts_dict ( `type` INT UNSIGNED NOT NULL COMMENT '2 は Jieba、3 は IK', `word` VARCHAR(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '辞書の単語', `is_added` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1 は追加、2 は削除' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='IMCI FTS ユーザー辞書';カスタム辞書自体は InnoDB テーブルです。読み取りおよび書き込み操作は、通常のテーブルと同じです。
単語を追加します。
INSERT INTO my_fts_dict VALUES(2, "PolarDB", 1)単語を削除します。
INSERT INTO my_fts_dict(type, word, is_added) VALUES(2, "PolarDB", 2); or DELETE FROM my_fts_dict WHERE type=2 AND word = "PolarDB";
カスタム辞書の設定
カスタム辞書テーブルを作成した後、
imci_fts_user_dict_tableパラメーターを設定します。たとえば、test/my_fts_dict'です。SET GLOBAL imci_fts_user_dict_table = 'test/my_fts_dict';imci_fts_user_dict_tableがすでに設定されている場合は、imci_fts_user_dict_updateを ON に設定して、imci_fts_user_dict_tableで指定されたカスタム辞書の再読み込みをトリガーすることもできます。SET GLOBAL imci_fts_user_dict_update = ON;説明新しいカスタム辞書は、それ以降に構築される転置インデックスにのみ有効になります。既存の転置インデックスに適用するには、転置インデックスを再構築する必要があります。
カスタムシノニム
IMCI フルテキストインデックス機能は、カスタムテーブルを使用してカスタムシノニムをサポートします。
カスタムシノニムテーブルの作成
まず、my_synonym_dict テーブルと同じ構造のテーブルを定義します。カラム名は my_synonym_dict テーブルのカラム名と一致する必要があります。
word:シノニムリスト。単語はカンマで区切ります。type:シノニムタイプ。0は、リスト内のすべての単語が互いにシノニムであることを示します。例えば、"db,database,polardb"は"db" <=> "database" <=> "polardb"を意味します。"db"、"database"、または"polardb"を検索すると、"db"、"database"、および"polardb"に一致するすべてのデータが返されます。1は、リストの最初の単語がプライマリタームであり、他の単語がそのシノニムであることを示します。例えば、"db,database,polardb"は"db" => "database", "polardb"を意味します。"db"を検索すると、"db"、"database"、および"polardb"に一致するすべてのデータが返されます。ただし、"database"を検索すると、"database"に一致するデータのみが返されます。
CREATE TABLE my_synonym_dict (
`word` VARCHAR(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'カンマ区切りのシノニム',
`type` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '0は等価、1はマッピング'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='IMCI FTS シノニム';カスタムシノニムテーブル自体は InnoDB テーブルです。読み取りおよび書き込み操作は、通常のテーブルと同様です。
単語の追加
INSERT INTO my_synonym_dict VALUES("db,database,polardb", 0); INSERT INTO my_synonym_dict VALUES("imci,clickhouse,duckdb", 1);単語の削除
DELETE FROM my_synonym_dict WHERE type=1 AND word = "imci,clickhouse,duckdb";
カスタムシノニムの設定
カスタムシノニムテーブルを作成した後、imci_fts_synonym_table パラメーターを設定します。例:test/my_synonym_dict。ここで、test はデータベース名、my_synonym_dict はテーブル名です。
SET GLOBAL imci_fts_synonym_table = 'test/my_synonym_dict';imci_fts_synonym_table がすでに設定されている場合は、imci_fts_synonym_update を ON に設定して、imci_fts_synonym_table で指定されたカスタムシノニムの再読み込みをトリガーすることもできます。
SET GLOBAL imci_fts_synonym_update = ON;synonym がインデックスモードに設定されている場合 (例: COMMENT "imci_fts(type=0 synonym=1)")、更新されたシノニムは新しくインデックスが作成されたデータにのみ有効になります。すべてのデータに変更を適用するには、フルテキストインデックスを再構築する必要があります。
カスタムストップワード
IMCI のフルテキストインデックス機能は、カスタムテーブルでカスタムストップワードをサポートします。
カスタムストップワードテーブルの作成
まず、my_stop_words テーブルと同じ構造のテーブルを定義します。カラム名は my_stop_words のカラム名と一致している必要があります。
word:ストップワード。is_added:カスタム辞書に単語を追加する (値 1) か、削除する (値 0) かを指定します。
CREATE TABLE my_stop_words (
`word` VARCHAR(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'ストップワード',
`is_added` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1 は追加、0 は削除'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='imci fts stop word';カスタムストップワードテーブル自体は InnoDB テーブルです。読み取り/書き込み操作は、通常のテーブルと同様です。
単語の追加
INSERT INTO my_stop_words VALUES("am", 1); INSERT INTO my_stop_words VALUES("chinese", 1);単語の削除
INSERT INTO my_stop_words(word, is_added) VALUES("chinese", 0); -- または DELETE FROM my_stop_words WHERE is_added=1 AND word = "chinese";
カスタムストップワードの設定
カスタムストップワードテーブルを作成した後、imci_fts_stop_word_table パラメーターを設定します。例:test/my_stop_words。ここで、test はデータベース名、my_stop_words はテーブル名です。
SET GLOBAL imci_fts_stop_word_table = 'test/my_stop_words';imci_fts_stop_word_table がすでに設定されている場合は、imci_fts_stop_word_update を ON に設定して、imci_fts_stop_word_table で指定されたカスタムストップワードの再読み込みを実行することもできます。
SET GLOBAL imci_fts_stop_word_update = ON;新しいカスタムストップワードは、これ以降に構築される転置インデックスにのみ有効になります。既存の転置インデックスに適用するには、転置インデックスを再構築する必要があります。
よくある質問
Q1: 適切なトークナイザーを選択するにはどうすればよいですか。
英語または書式設定されたテキスト:デフォルトの
type=0(トークン) を使用します。これは、スペースや句読点でテキストを分割します。正確な中国語検索:
type=2(jieba) またはtype=3(ik) のデフォルトモードを使用します。JSON コンテンツ検索:
type=4(json) を使用し、exprパラメーターでインデックスを作成する JSON パスを指定します。dbms_imci.fts_tokenize 関数を使用して、異なるトークナイザーがテキストをどのように処理するかをプレビューできます。
Q2: クエリがフルテキストインデックスを使用しないのはなぜですか。
SET imci_enable_fts_query = ON;が実行されていることを確認してください。これが最も一般的な原因です。EXPLAINの出力を確認し、FtsTableScanオペレーターが存在するかどうかを確認してください。存在しない場合、クエリパターンがインデックスと一致していないか、システムがフルテーブルスキャンの方がコストが低いと判断した可能性があります。
Q3: LIKE クエリと MATCH...AGAINST の違いは何ですか。
フルテキストインデックスのない
LIKE '%keyword%'は、フルテーブルスキャンを引き起こし、パフォーマンスが低下します。 IMCI によって高速化された場合でも、その機能は比較的限定的です。MATCH...AGAINSTは、全文検索専用に設計された構文です。高いパフォーマンスを提供し、将来的にはブールクエリや関連性スコアリングなどのより高度な機能をサポートする予定です。新しいアプリケーションにはMATCH...AGAINSTの使用を推奨します。