このトピックでは、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 では、テーブル作成時に列の comment を指定するか、DDL を使用して列の 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
列値全体を単一の語彙として扱います。主に
=またはINを使用した等価検索の高速化に使用されます。構成パラメーター (
KEY-VALUEペア):パラメーター (KEY)
デフォルト
説明
適用可能なトークナイザータイプ (
type)enable
1
1(デフォルト):転置インデックスを作成します。0:転置インデックスを削除します。
すべて
type
0
トークナイザータイプを指定します。詳細については、上記の表をご参照ください。
すべて
len
-
ngramトークナイザーにおけるトークン長です。値の範囲は[2, 256)です。type=1(ngram)mode
0
トークナイザーモード:
jieba(
type=2):0(デフォルト):正確モード1:完全モード2:検索エンジンモード
ik(
type=3):0(デフォルト):スマートモード1:細かい粒度モード
json(
type=4):0(デフォルト):配列モード
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:大文字小文字を区別する。
すべて
使用例
ステップ 1:フルテキストインデックスの作成
検索対象の列にフルテキストインデックスを作成し、ビジネス要件に応じてトークナイザーを選択します。
インメモリ列指向インデックス (IMCI) を備えたテストテーブルを作成します。
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"] -- ngram トークナイザー CALL dbms_imci.fts_tokenize("I am PolarDB", "type=1"); -- 結果: ["i ", " a", "am", "m ", " p", "po", "ol", "ar", "rd", "db"] -- jieba トークナイザー CALL dbms_imci.fts_tokenize("I am PolarDB", "type=2"); -- 結果: ["PolarDB"] -- jieba トークナイザー、完全モード 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 フルテキストインデックス機能のタイトル'), (17, 'データベースのタイトルとパフォーマンス最適化'); -- title 列に「タイトル」を含むレコードをクエリ SELECT * FROM t1 WHERE MATCH(title) AGAINST("タイトル");EXPLAINコマンドを実行して実行計画を表示します。FtsTableScan演算子は、クエリがフルテキストインデックスを使用したことを示します。EXPLAIN SELECT * FROM t1 WHERE MATCH(title) AGAINST("タイトル") AND id > 10; +----+------------------------+------+-----------------------------------------------------------------+ | ID | 演算子 | 名前 | 追加情報 | +----+------------------------+------+-----------------------------------------------------------------+ | 1 | Select Statement | | IMCI 実行計画 (max_dop = 32, max_query_mem = 41230008320) | | 2 | └─Compute Scalar | | | | 3 | └─FILTER | | 条件:(t1.id > 10) | | 4 | └─FtsTableScan | t1 | ターム:("タイトル") フォールバック:(t1.title LIKE "%タイトル%") | +----+------------------------+------+-----------------------------------------------------------------+Fallbackフィールドは、インデックス化されていない増分データに対して、システムが自動的にLIKE述語を用いた補足スキャンを実行し、結果の完全性を確保することを示します。LIKEクエリの高速化: 既存のアプリケーションコードとの互換性を確保するため、IMCI は特定のLIKEクエリを自動的にMATCH...AGAINSTクエリに変換して高速化できます。SET imci_convert_like_to_match = on; EXPLAIN SELECT * FROM t1 WHERE title LIKE "%タイトル%"; +----+------------------------+------+-----------------------------------------------------------------+ | ID | 演算子 | 名前 | 追加情報 | +----+------------------------+------+-----------------------------------------------------------------+ | 1 | Select Statement | | IMCI 実行計画 (max_dop = 32, max_query_mem = 41230008320) | | 2 | └─Compute Scalar | | | | 3 | └─FILTER | | 条件:(t1.title LIKE "%タイトル%") | | 4 | └─FtsTableScan | t1 | ターム:("タイトル") フォールバック:(t1.title LIKE "%タイトル%") | +----+------------------------+------+-----------------------------------------------------------------+実行計画にも
FtsTableScan演算子が表示され、IMCI がLIKEクエリを正常に高速化したことが確認できます。MATCHをLIKEに変換: フルテキストインデックスが利用できない場合、IMCI はMATCHクエリをLIKEクエリに変換し、クエリが引き続き実行可能であるとともに、可能な限り既存のインデックスを活用できるようにします。実行計画には全表スキャンが表示されます。SET imci_enable_query_fts_like = on; EXPLAIN SELECT * FROM t1 WHERE MATCH(title) AGAINST("タイトル"); +----+----------------------+------+-----------------------------------------------------------------+ | ID | 演算子 | 名前 | 追加情報 | +----+----------------------+------+-----------------------------------------------------------------+ | 1 | Select Statement | | IMCI 実行計画 (max_dop = 32, max_query_mem = 41230008320) | | 2 | └─Compute Scalar | | | | 3 | └─Table Scan | t1 | 条件:(title LIKE "%タイトル%") | +----+----------------------+------+-----------------------------------------------------------------+
ステップ 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 | グローバル | 転置インデックス辞書のキャッシュ容量です。 値の範囲:ノードクラスのメモリの 10% ~ 50%。デフォルト:ノードクラスのメモリの 10%。 |
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 | グローバル |
説明 このパラメーターは、以下のバージョンでのみ利用可能です:
|
Global レベルのパラメーターは、コマンドラインから直接変更できません。コンソールでのみ設定可能です。クライアントでコマンドを実行した場合、クライアントはデフォルトでセッションレベルの操作として処理します。
カスタム辞書
IMCI フルテキストインデックス機能は、カスタムテーブルを用いたカスタム辞書をサポートしており、ビジネスシナリオに合わせたより適切なトークン化結果を実現できます。
カスタム辞書テーブルの作成
まず、
my_fts_dictテーブルと同じ構造および列名を持つテーブルを作成します。type:トークナイザータイプ。Jieba(type2)および ik(type3)トークナイザーのみサポートされます。word:エンティティ単語。is_added:カスタム辞書への単語の追加(値1)または削除(値2)を指定します。
CREATE TABLE my_fts_dict ( `type` INT UNSIGNED NOT NULL COMMENT '2 for jieba, 3 for ik', `word` VARCHAR(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'dict word', `is_added` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1 for add, 2 for delete' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='imci fts user dict';カスタム辞書は InnoDB テーブルである必要があります。他のテーブルと同様に、読み取りおよび書き込み操作が可能です。
単語の追加:
INSERT INTO my_fts_dict VALUES(2, "PolarDB", 1)単語の削除:
INSERT INTO my_fts_dict(type, word, is_added) VALUES(2, "PolarDB", 2); または 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に設定することで、辞書の再読み込みをトリガーできます。SET GLOBAL imci_fts_user_dict_update = ON;説明新しいカスタム辞書は、更新後に構築された転置インデックスにのみ適用されます。既存の転置インデックスに変更を適用するには、再構築する必要があります。
よくある質問
Q1: 適切なトークナイザーの選択方法を教えてください。
英語または整形済みテキストの場合は、空白および句読点でテキストを分割するデフォルトの
tokenトークナイザー(type=0)を使用します。中国語の精密検索の場合は、デフォルトモードの
jieba(type=2)またはik(type=3)トークナイザーを使用します。JSON フィールド内のコンテンツを検索する場合は、
jsonトークナイザー(type=4)を使用し、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の使用を優先することを推奨します。