すべてのプロダクト
Search
ドキュメントセンター

ApsaraDB for SelectDB:転置インデックス

最終更新日:May 14, 2026

転置インデックスは、情報検索における一般的なインデックス技術です。テキストをトークン化してタームに変換し、インデックスを構築することで、それらのタームを含むドキュメントを迅速に取得できます。ApsaraDB for SelectDB は転置インデックスをサポートしています。この機能を使用することで、テキストデータ型の全文検索や、数値および日付データ型の等価クエリおよび範囲クエリを実行でき、大規模なデータセットから特定のデータを迅速にフィルターできます。このトピックではApsaraDB for SelectDB の転置インデックス機能について、その作成方法と使用方法を含めて説明します。

仕組み

Alibaba Cloud SelectDB では、転置インデックスはテーブルの行をドキュメントとして、列をフィールドとして扱います。これにより、転置インデックスは特定のキーワードを含む行を迅速に特定できるようになり、WHERE 句を使用するクエリのパフォーマンスが向上します。

通常のインデックスとは異なり、転置インデックスは独立した転置ファイルに保存されます。このファイルは論理的にセグメントファイルにマッピングされていますが、統合はされていません。このアプローチにより、インデックスの更新や削除時にセグメントファイルを書き換える必要がなくなり、処理オーバーヘッドが大幅に削減されます。

シナリオ

  • 文字列データ型の全文検索を高速化します。

  • 文字列型、数値型、および日時型での =, !=, >, >=, <, <= によるフィルタリングを高速化します。

メリット

  • 論理演算子の包括的なサポート。

    • OR と NOT ロジックのインデックスプッシュダウンをサポートするようになりました。

    • 複数の条件による AND、OR、NOT の任意の組み合わせをサポートしています。

  • 柔軟で高速なインデックス管理。

    • テーブルの作成時に転置インデックスを作成します。

    • 既存のテーブルに転置インデックスを追加します。

    • テーブルから転置インデックスを削除します。

制限事項

  • FLOAT および DOUBLE 浮動小数点データ型は、精度に問題があるため転置インデックスをサポートしていません。代わりに、転置インデックスをサポートする DECIMAL 固定小数点データ型を使用してください。

  • 一部の複合データ型は転置インデックスをサポートしていません。これには、MAPSTRUCTJSONHLLBITMAPQUANTILE_STATE、および AGG_STATE などが含まれます。JSON データで転置インデックスを使用するには、列を VARIANT データ型に変換してください。

  • 数値型のフィールドに転置インデックスを作成できますが、parserenglishchineseunicode など) を指定することはできません。

  • DUPLICATE モデル、およびマージオンライトが有効な UNIQUE モデルは、任意の列で転置インデックスをサポートしています。一方、AGGREGATE モデル、およびマージオンライトが無効な UNIQUE モデルでは、キー列でのみ転置インデックスをサポートしています。これらのモデルでは、すべてのデータを読み取ってマージする必要があるため、システムは事前フィルタリングにインデックスを使用できません。

インデックスの作成

転置インデックスは、テーブル作成時に作成するか、既存テーブルの列に対して作成することができます。

テーブル作成時のインデックス作成

同期操作です。インデックスの作成は、テーブルが正常に作成されると完了します。

重要

転置インデックスには、データモデルごとに以下の制限事項があります。

  • Aggregate Key モデルの場合、転置インデックスはキー列にのみ作成できます。

  • Unique Key モデルの場合、Merge on Write 機能を有効にする必要があります。有効にすると、任意の列に転置インデックスを作成できます。

  • Duplicate Key モデルの場合、任意の列に転置インデックスを作成できます。

構文

CREATE TABLE  [IF NOT EXISTS] [db_name.]<table_name>
(
  <column_definition_list>,
  [<index_definition_list>] 
)
table_properties;

パラメータ

テーブル作成パラメータ

パラメータ

必須

説明

db_name

任意

テーブルを含むデータベースの名前。

table_name

必須

作成するテーブルの名前。

column_definition_list

必須

列定義のリスト。詳細については、「CREATE-TABLE」をご参照ください。

table_properties

必須

データモデル、パーティショニング、バケット化などのテーブルプロパティ。詳細については、「データモデル」をご参照ください。

index_definition_list

任意

インデックス定義のリスト。

index_definition_list

テーブルを作成するときに、1 つ以上のインデックスを定義できます。次の形式を使用します: index_definition[, index_definition][, index_definition]...

index_definition

INDEX <index_name>(<column_name>) <index_type> [PROPERTIES("<key>" = "<value>")] [COMMENT '<comment>']

パラメータ

必須パラメータ

パラメータ

説明

index_name

インデックスの名前。

column_name

インデックスを作成する列の名前。

index_type

インデックスタイプ。これを USING INVERTED に設定します。

任意パラメータ
プロパティ

PROPERTIES 句は、インデックスのトークン化オプションを指定します。これは、"<key>" = "<value>" の形式でカンマで区切られた 1 つ以上のキーと値のペアで構成されています。特定のテキストがどのようにトークン化されるかわからない場合は、TOKENIZE 関数を使用して出力を表示します。詳細については、「トークン化関数」をご参照ください。

キー

parser

トークナイザーを指定します。このプロパティを省略すると、トークン化は行われません。 parser プロパティは数値データ型ではサポートされていません。

  • english: 英語のトークナイザー。英語のテキストに最適で、この高性能なトークナイザーはスペースと句読点に基づいて単語を分割します。

  • chinese: 中国語のトークナイザー。中国語の文字を含むテキストに適しています。パフォーマンスは英語のトークナイザーよりも低くなります。

  • unicode: Unicode トークナイザー。中国語と英語などの多言語が混在するテキストに適しています。メールのプレフィックスとサフィックス、IP アドレス、英数字の文字列をトークン化できます。また、中国語のテキストを文字ごとにトークン化します。

parser_mode

単語のトークン化モードを指定します。これにより、トークン化の粒度が決まります。

すべてのトークナイザーは、デフォルトで coarse_grained モードを使用します。このモードは、テキストをより長い単語に分割する傾向があります。たとえば、'Wuhan City Yangtze River Bridge''Wuhan City''Yangtze River Bridge' の 2 つの単語に分割されます。

中国語トークナイザーで parser=chinese が指定されている場合、fine_grained モードもサポートされます。このモードは、テキストをより短い単語にトークン化する傾向があります。たとえば、'Wuhan City Yangtze River Bridge''Wuhan''Wuhan City''mayor''Yangtze River''Yangtze River Bridge''Bridge' の 6 つのトークンにトークン化されます。

トークン化の仕組みの詳細については、「トークン化関数」をご参照ください。

support_phrase

インデックスが高速化された MATCH_PHRASE フレーズクエリをサポートするかどうかを指定します。デフォルトは false です。

  • true: サポートを有効にします。これにはより多くのストレージ領域が必要です。

  • false: ストレージ領域を節約するためにサポートを無効にします。 MATCH_ALL を使用して複数のタームをクエリできます。

char_filter

トークン化の前に文字列を前処理します。現在、char_filter_typechar_replace のみをサポートしています。

char_replace は、char_filter_pattern 内の各文字を char_filter_replacement の対応する文字に置き換えます。

  • char_filter_pattern: 置き換えられる文字の配列。

  • char_filter_replacement: 置換後の文字の配列。このプロパティは任意であり、省略した場合は単一のスペース文字がデフォルトです。

ignore_above

トークン化されていない文字列値 (parser が指定されていない場合) の長さ制限を指定します。

  • システムは ignore_above の値より長い文字列をインデックスに登録しません。文字列配列の場合、この制限は各要素に適用されます。

  • デフォルト: 256 (バイト)。

lower_case

大文字と小文字を区別しないマッチングのために、トークン化されたタームを小文字に変換するかどうかを指定します。

  • true: 小文字に変換します。

  • false: 元のケースを保持します。

stopwords

ストップワードのリストを指定します。これはトークナイザーの動作に影響します。

  • 組み込みリストには、システムがインデックス作成時およびクエリ時に無視する、一般的で価値の低い単語 (isthea など) が含まれます。

  • none: 空のストップワードリストを使用します。

dict_compression

転置インデックスの辞書に対して Zstandard (ZSTD) 辞書圧縮を有効にするかどうかを指定します。

  • true: 辞書圧縮を有効にします。

  • false: (デフォルト) 辞書圧縮を無効にします。

  • 推奨事項: 大量のテキストまたはログのワークロードの場合、またはストレージコストを削減するためにこれを有効にすることを推奨します。 inverted_index_storage_format = "V3" と組み合わせると最も効果的で、大規模なテキストおよびログデータの場合、ストレージを約 20% 削減できます。

説明

このパラメータは、バージョン 4.1.0 以降でのみサポートされています。

コメント

パラメータ

説明

comment

インデックスの説明。

例: インデックスを持つテーブルの作成

-- テーブルを作成し、comment 列に idx_comment という名前の転置インデックスを作成します。
-- USING INVERTED は、インデックスタイプを転置インデックスに設定します。
-- PROPERTIES("parser" = "english") は、トークナイザーを "english" に設定します。他のサポートされているトークナイザーには、中国語テキスト用の "chinese" や、多言語が混在するテキスト用の "unicode" があります。"parser" プロパティを省略すると、トークン化は行われません。
CREATE TABLE hackernews_1m
(
    `id` BIGINT,
    `deleted` TINYINT,
    `type` String,
    `author` String,
    `timestamp` DateTimeV2,
    `comment` String,
    `dead` TINYINT,
    `parent` BIGINT,
    `poll` BIGINT,
    `children` Array<BIGINT>,
    `url` String,
    `score` INT,
    `title` String,
    `parts` Array<INT>,
    `descendants` INT,
    INDEX idx_comment (`comment`) USING INVERTED PROPERTIES("parser" = "english") COMMENT 'inverted index for comment'
)
DUPLICATE KEY(`id`)
DISTRIBUTED BY HASH(`id`) BUCKETS 10;

インデックスの追加

このオペレーションは非同期オペレーションです。インデックス作成の進捗は、SHOW ALTER TABLE COLUMN; を使用して確認できます。

構文

ALTER TABLE <table_name> ADD INDEX <index_name>(<column_name>) <index_type> [PROPERTIES("<key>" = "<value>")];

パラメータ

パラメータは、テーブル作成時と同じです。

トークン化なしでインデックスを追加します。

ALTER TABLE user_tb ADD INDEX index_userId(user_id) USING INVERTED ;

トークン化に english を使用するインデックスを追加します。

ALTER TABLE user_tb ADD INDEX index_city(city) USING INVERTED PROPERTIES("parser" = "english");

転置インデックスの表示

インデックス変更の進捗の表示

ALTER コマンドと DROP コマンドを使用した転置インデックスの変更は、非同期プロセス です。進捗を表示するには、次のステートメントを使用します。

SHOW ALTER TABLE COLUMN;

テーブル内のすべてのインデックスの表示

構文

SHOW INDEXES FROM <table_name>;

SHOW INDEXES FROM user_tb;

インデックスの削除

インデックスの削除は非同期プロセスです。進行状況を確認するには、「転置インデックス情報のクエリ」 をご参照ください。

重要

インデックスを削除すると、クエリパフォーマンスが低下する可能性があります。慎重に実行してください。

構文

-- 構文 1
DROP INDEX <index_name> ON <table_name>;
-- 構文 2
ALTER TABLE <table_name> DROP INDEX <index_name>;

DROP INDEX index_userId ON user_tb;
ALTER TABLE user_tb DROP INDEX index_city;

転置インデックス

全文検索

構文

SELECT * FROM <table_name> WHERE <column_name> <conditional_logic> '<keywords>';

パラメーター

パラメーター

必須

説明

table_name

はい

テーブルの名前です。

column_name

はい

カラムの名前です。

conditional_logic

はい

検索演算子と論理演算子の組み合わせです。

論理演算子: AND、OR、NOT

検索演算子:

  • MATCH_ALL: 指定されたすべてのキーワードを含む行を返します。

  • MATCH_ANY: 指定されたいずれかのキーワードを含む行を返します。

  • MATCH_PHRASE: 正確なフレーズを含む行を返します。

keywords

はい

検索キーワードです。

複数のキーワードはスペースで区切ります。

例: keyword1 keyword2 keyword3

-- logmsg に keyword1 を含む行を取得します。
SELECT * FROM log_tb WHERE logmsg MATCH_ANY 'keyword1';

-- logmsg に keyword1 または keyword2 を含む行を取得します。
SELECT * FROM log_tb WHERE logmsg MATCH_ANY 'keyword1 keyword2';

-- logmsg に keyword1 と keyword2 の両方を含む行を取得します。
SELECT * FROM log_tb WHERE logmsg MATCH_ALL 'keyword1 keyword2';

-- logmsg に正確なフレーズ "keyword1 keyword2" を含む行を取得します。
SELECT * FROM log_tb WHERE logmsg MATCH_PHRASE 'keyword1 keyword2';

数値と日付に対する等価クエリと範囲クエリ

クエリ構文は標準 SQL 構文です。

-- 等価、範囲、IN クエリ
SELECT * FROM user_tb WHERE id = 123;
SELECT * FROM user_tb WHERE ts > '2023-01-01 00:00:00';
SELECT * FROM user_tb WHERE op_type IN ('add', 'delete');

クエリパフォーマンスの比較

このトピックでは、100 万行の hackernews データセットを使用して、転置インデックスの有無によるクエリパフォーマンスを比較します。

前提条件

ステップ 1:テーブルを作成します。

  1. データベースを作成します。

    CREATE DATABASE test_inverted_index;
  2. 作成したデータベースに切り替えます。

    USE test_inverted_index;
  3. 対象テーブルを作成します。

    CREATE TABLE hackernews_1m
    (
        `id` BIGINT,
        `deleted` TINYINT,
        `type` String,
        `author` String,
        `timestamp` DateTimeV2,
        `comment` String,
        `dead` TINYINT,
        `parent` BIGINT,
        `poll` BIGINT,
        `children` Array<BIGINT>,
        `url` String,
        `score` INT,
        `title` String,
        `parts` Array<INT>,
        `descendants` INT,
        INDEX idx_comment (`comment`) USING INVERTED PROPERTIES("parser" = "english") COMMENT 'inverted index for comment'
    )
    DUPLICATE KEY(`id`)
    DISTRIBUTED BY HASH(`id`) BUCKETS 10;
    -- テーブルを作成し、comment 列に idx_comment という名前の転置インデックスを作成します。
    -- USING INVERTED は、インデックスタイプが転置インデックスであることを指定します。
    -- PROPERTIES("parser" = "english") は、英語トークナイザーを使用することを指定します。中国語テキストの場合は "chinese"、複数言語が混在するテキストの場合は "unicode" を指定することもできます。"parser" パラメーターを指定しない場合、トークン化は実行されません。

ステップ 2:データをインポートします。

  1. データファイルをダウンロードします。

    wget https://qa-build.oss-cn-beijing.aliyuncs.com/regression/index/hacknernews_1m.csv.gz
  2. Stream Load を使用してデータをインポートします。

    ApsaraDB for SelectDB のインスタンス詳細ページで、ApsaraDB for SelectDB インスタンスのエンドポイントホストとポート番号を確認できます。Stream Load の詳細については、Stream Load をご参照ください。

    curl --location-trusted -u root: -H "compress_type:gz" -T hacknernews_1m.csv.gz  http://<host>:<port>/api/test_inverted_index/hackernews_1m/_stream_load
    {
        "TxnId": 2,
        "Label": "a8a3e802-2329-49e8-912b-04c800a461a6",
        "TwoPhaseCommit": "false",
        "Status": "Success",
        "Message": "OK",
        "NumberTotalRows": 1000000,
        "NumberLoadedRows": 1000000,
        "NumberFilteredRows": 0,
        "NumberUnselectedRows": 0,
        "LoadBytes": 130618406,
        "LoadTimeMs": 8988,
        "BeginTxnTimeMs": 23,
        "StreamLoadPutTimeMs": 113,
        "ReadDataTimeMs": 4788,
        "WriteDataTimeMs": 8811,
        "CommitAndPublishTimeMs": 38
    }
  3. count() クエリを実行して、データインポートを確認します。

    SELECT count() FROM hackernews_1m;
    +---------+
    | count() |
    +---------+
    | 1000000 |
    +---------+
    1 row in set (0.02 sec)

パフォーマンスの比較

説明
  • トークナイザー付きの転置インデックスを使用するクエリと使用しないクエリでは、カウント結果が異なる場合があります。これは、転置インデックスが列データをトークン化し、ターム (例:小文字への変換) を正規化するため、インデックスを使用するクエリがより多くの行に一致する可能性があるためです。

  • 一部の例では、データセットが小さいため、パフォーマンスの差が顕著でない場合があります。データセットが大きくなるほど、パフォーマンスの向上が大きくなります。

全文検索
  • comment 列に OLAP が含まれる行数をカウントします。

    • LIKE 演算子を使用して comment 列で OLAP を含む行数をカウントすると、0.18 秒かかります。

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%';
      +---------+
      | count() |
      +---------+
      |      34 |
      +---------+
      1 row in set (0.18 sec)
    • 転置インデックスに基づく MATCH_ANY 全文検索は、comment 列で OLAP を含む行数を 0.02 秒でカウントします。これは、LIKE 演算子を使用する場合よりも 9 倍高速です。

      SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLAP';
      +---------+
      | count() |
      +---------+
      |      35 |
      +---------+
      1 行 (0.02 秒)
  • comment カラムに OLTP が含まれる行をカウントします。

    • この操作は、LIKE 演算子を使用して、comment カラムで OLTP を含む行数をカウントし、0.07 秒かかります。

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      48 |
      +---------+
      1 row in set (0.07 sec)
    • 転置インデックスに基づく MATCH_ANY 全文検索は、comment 列で OLTP を含む行数を 0.01 秒でカウントします。これは LIKE 演算子を使用する場合よりも 7 倍高速です。

      SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLTP';
      +---------+
      | count() |
      +---------+
      |      51 |
      +---------+
      1 row in set (0.01 sec)
  • comment 列に OLAPOLTP の両方が含まれる行数をカウントします。

    • LIKE を使用すると、クエリは 0.13 秒かかります。

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' AND comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      14 |
      +---------+
      1 row in set (0.13 sec)
    • MATCH_ALL を使用した全文検索では、クエリの所要時間は 0.01 秒となり、LIKE を使用する場合より 13 倍高速です。

       SELECT count() FROM hackernews_1m WHERE comment MATCH_ALL 'OLAP OLTP';
      +---------+
      | count() |
      +---------+
      |      15 |
      +---------+
      1 row in set (0.01 sec)
  • comment 列に OLAP または OLTP のいずれかが含まれている行数をカウントします。

    • LIKE を使用すると、クエリは 0.12 秒かかります。

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' OR comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      68 |
      +---------+
      1 row in set (0.12 sec)
    • MATCH_ANY による全文検索を使用すると、クエリは 0.01 秒で完了し、LIKE を使用する場合の 12 倍高速です。

      SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLAP OLTP';
      +---------+
      | count() |
      +---------+
      |      71 |
      +---------+
      1 row in set (0.01 sec)

等価クエリと範囲クエリ

  • DateTimeV2 列に対する範囲クエリのパフォーマンスを比較します。

    1. 転置インデックスがない場合、timestamp2007-08-23 04:17:00 より大きい行数をカウントするクエリは 0.03s かかります。

       SELECT count() FROM hackernews_1m WHERE timestamp > '2007-08-23 04:17:00';
      +---------+
      | count() |
      +---------+
      |  999081 |
      +---------+
      1 row in set (0.03 sec)
    2. timestamp 列に転置インデックスを追加します。

      CREATE INDEX idx_timestamp ON hackernews_1m(timestamp) USING INVERTED;
      Query OK, 0 rows affected (0.03 sec)
    3. インデックス作成の進行状況を確認します。FinishTime と CreateTime の差から、timestamp 列の 100 万行に対する転置インデックスの作成にかかった時間はわずか 1 秒であることがわかります。

      SHOW ALTER TABLE COLUMN;
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      | JobId | TableName     | CreateTime              | FinishTime              | IndexName     | IndexId | OriginIndexId | SchemaVersion | TransactionId | State    | Msg  | Progress | Timeout |
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      | 10030 | hackernews_1m | 2023-02-10 19:44:12.929 | 2023-02-10 19:44:13.938 | hackernews_1m | 10031   | 10008         | 1:1994690496  | 3             | FINISHED |      | NULL     | 2592000 |
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      1 row in set (0.00 sec)
    4. 転置インデックスを作成した後、timestamp 列が 2007-08-23 04:17:00 より大きいデータをカウントする同じクエリは 0.01 秒で実行されます。これは、転置インデックスがない場合と比較して 2 秒の高速化に相当します。

      SELECT count() FROM hackernews_1m WHERE timestamp > '2007-08-23 04:17:00';
      +---------+
      | count() |
      +---------+
      |  999081 |
      +---------+
      1 行 (0.01 秒)
  • 数値列に対する等価クエリのパフォーマンスを比較します。

    1. 転置インデックスがない場合、parent 列が 11189 に等しい行をカウントするクエリは 0.01 秒かかります。

      SELECT count() FROM hackernews_1m WHERE parent = 11189;
      +---------+
      | count() |
      +---------+
      |       2 |
      +---------+
      1 row in set (0.01 sec)
    2. 数値型の parent 列にトークナイザーなしで転置インデックスを作成します。

      -- 数値型の場合、INVERTED を使用する際にトークナイザーを指定する必要はありません。
      -- ALTER TABLE ... ADD INDEX は、インデックスを作成するための代替構文です。
      ALTER TABLE hackernews_1m ADD INDEX idx_parent(parent) USING INVERTED;
      Query OK, 0 rows affected (0.01 sec)
    3. インデックス作成の進行状況を確認します。

      SHOW ALTER TABLE COLUMN;
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      | JobId | TableName     | CreateTime              | FinishTime              | IndexName     | IndexId | OriginIndexId | SchemaVersion | TransactionId | State    | Msg  | Progress | Timeout |
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      | 10030 | hackernews_1m | 2023-02-10 19:44:12.929 | 2023-02-10 19:44:13.938 | hackernews_1m | 10031   | 10008         | 1:1994690496  | 3             | FINISHED |      | NULL     | 2592000 |
      | 10053 | hackernews_1m | 2023-02-10 19:49:32.893 | 2023-02-10 19:49:33.982 | hackernews_1m | 10054   | 10008         | 1:378856428   | 4             | FINISHED |      | NULL     | 2592000 |
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
    4. 同じクエリを再度実行します。クエリ時間は 0.01 秒のままで、このデータセットでは大きな変化は見られません。

      SELECT count() FROM hackernews_1m WHERE parent = 11189;
      +---------+
      | count() |
      +---------+
      |       2 |
      +---------+
      1 row in set (0.01 sec)
  • 文字列列に対する等価クエリのパフォーマンスを比較します。

    1. 転置インデックスがない場合、author 列が 'faster' に等しい行をカウントするクエリは 0.03 秒かかります。

      SELECT count() FROM hackernews_1m WHERE author = 'faster';
      +---------+
      | count() |
      +---------+
      |      20 |
      +---------+
      1 row in set (0.03 sec)
    2. author 列にトークナイザーなしで転置インデックスを作成します。

      -- この例では、USING INVERTED のみが指定されています。author 列の値はトークン化されず、各値は単一のタームとして扱われます。
      ALTER TABLE hackernews_1m ADD INDEX idx_author(author) USING INVERTED;
      Query OK, 0 rows affected (0.01 sec)
    3. インデックス作成の進行状況を確認します。

      -- 100 万行のデータを持つ author 列にインデックスを段階的に作成するのに、わずか 1.5 秒しかかかりません。
      SHOW ALTER TABLE COLUMN;
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      | JobId | TableName     | CreateTime              | FinishTime              | IndexName     | IndexId | OriginIndexId | SchemaVersion | TransactionId | State    | Msg  | Progress | Timeout |
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      | 10030 | hackernews_1m | 2023-02-10 19:44:12.929 | 2023-02-10 19:44:13.938 | hackernews_1m | 10031   | 10008         | 1:1994690496  | 3             | FINISHED |      | NULL     | 2592000 |
      | 10053 | hackernews_1m | 2023-02-10 19:49:32.893 | 2023-02-10 19:49:33.982 | hackernews_1m | 10054   | 10008         | 1:378856428   | 4             | FINISHED |      | NULL     | 2592000 |
      | 10076 | hackernews_1m | 2023-02-10 19:54:20.046 | 2023-02-10 19:54:21.521 | hackernews_1m | 10077   | 10008         | 1:1335127701  | 5             | FINISHED |      | NULL     | 2592000 |
      +-------+---------------+-------------------------+-------------------------+---------------+---------+---------------+---------------+---------------+----------+------+----------+---------+
      
    4. インデックスの作成後、クエリはわずか 0.01 秒で完了し、3 倍速くなります。

      -- インデックスの作成後、文字列の等価マッチングも大幅に高速化されます。
      SELECT count() FROM hackernews_1m WHERE author = 'faster';
      +---------+
      | count() |
      +---------+
      |      20 |
      +---------+
      1 row in set (0.01 sec)

TOKENIZE 関数

TOKENIZE 関数は、テキスト文字列を一連のタームに分割します。トークン化は、転置インデックスを構築して使用するためのコアコンポーネントです。トークン化の品質は、インデックスのパフォーマンスに直接影響します。

文字列がどのようにトークン化されるかを確認するには、TOKENIZE 関数を使用して結果を表示します。TOKENIZE 関数には、parserparser_mode という 2 つの主要なパラメーターがあります。次の表で、これらのパラメーターについて説明します。

パラメーター

説明

parser

使用するトークナイザーを指定します。このパラメーターを省略すると、関数はトークン化を実行しません。

  • english:英語のトークナイザー。これは、英語のテキストを含むフィールドに適しています。スペースと句読点に基づいてテキストをトークン化し、高いパフォーマンスを提供します。

  • chinese:中国語のトークナイザー。これは、中国語のテキストを含むフィールドに適しています。英語のトークナイザーよりもパフォーマンスが低くなります。

  • unicode:多言語混在トークナイザー。これは、中国語と英語などの多言語混在テキストに適しています。メールのプレフィックスとサフィックス、IP アドレス、英数字の文字列をトークン化します。また、中国語のテキストを文字ごとにトークン化します。

parser_mode

トークン化モードを指定します。これにより、トークン化の粒度が決まります。

すべてのトークナイザーは、デフォルトで粗粒度モードを使用します。このモードは、テキストをより長い単語に分割する傾向があります。たとえば、文字列 '武汉市长江大桥' は、'武汉市''长江大桥' の 2 つの単語に分割されます。

中国語のトークナイザーに parser=chinese が指定されている場合、細粒度モードもサポートされます。細粒度モードは、テキストをより短い単語に分割する傾向があります。たとえば、'武汉市长江大桥' は、'武汉''武汉市''市长''长江''长江大桥''大桥' の 6 つの単語にトークン化されます。

例:

-- 英語のトークン化結果。
SELECT TOKENIZE('I love CHINA','"parser"="english"');
+------------------------------------------------+
| tokenize('I love CHINA', '"parser"="english"') |
+------------------------------------------------+
| ["i", "love", "china"]                         |
+------------------------------------------------+
1 row in set (0.02 sec)

-- 中国語トークナイザー (細粒度モード) のトークン化結果。
SELECT TOKENIZE('武汉市长江大桥','"parser"="chinese","parser_mode"="fine_grained"');
+-------------------------------------------------------------------------------------+
| tokenize('武汉市长江大桥', '"parser"="chinese","parser_mode"="fine_grained"')         |
+-------------------------------------------------------------------------------------+
| ["武汉", "武汉市", "市长", "长江", "长江大桥", "大桥"]                                |
+-------------------------------------------------------------------------------------+
1 row in set (0.02 sec)

-- 中国語トークナイザー (粗粒度モード) のトークン化結果。
SELECT TOKENIZE('武汉市长江大桥','"parser"="chinese","parser_mode"="coarse_grained"');
+----------------------------------------------------------------------------------------+
| tokenize('武汉市长江大桥', '"parser"="chinese","parser_mode"="coarse_grained"')        |
+----------------------------------------------------------------------------------------+
| ["武汉市", "长江大桥"]                                                                 |
+----------------------------------------------------------------------------------------+
1 row in set (0.02 sec)

-- 多言語混在のトークン化結果。
SELECT TOKENIZE('I love CHINA 我爱我的祖国','"parser"="unicode"');
+-------------------------------------------------------------------+
| tokenize('I love CHINA 我爱我的祖国', '"parser"="unicode"')       |
+-------------------------------------------------------------------+
| ["i", "love", "china", "我", "爱", "我", "的", "祖", "国"]        |
+-------------------------------------------------------------------+
1 row in set (0.02 sec)