All Products
Search
Document Center

ApsaraDB for SelectDB:Inverted index

Last Updated:May 13, 2026

An inverted index is a common indexing technique in information retrieval. It works by tokenizing text into terms to build an index, enabling the quick retrieval of documents containing those terms.ApsaraDB for SelectDB supports inverted indexes. You can use this feature to perform full-text searches on text data types and run equality and range queries on numeric and date data types, which allows you to quickly filter large datasets for specific data.This topic describes the inverted index feature in ApsaraDB for SelectDB, including how to create and use it.

How it works

In Alibaba Cloud SelectDB, the inverted index treats a table row as a document and a column as a field. This enables the inverted index to quickly locate rows containing a specific keyword, improving the performance of queries that use a WHERE clause.

Unlike a regular index, an inverted index is stored in a separate inverted file. This file is logically mapped to the segment file but is not integrated with it. This approach avoids rewriting the segment file for index updates and deletions, significantly reducing processing overhead.

Scenarios

  • Accelerates full-text search on string data types.

  • Accelerates =, !=, >, >=, <, <= filtering for string, numeric, and datetime types.

Benefits

  • Comprehensive support for logical operators.

    • Added support for index pushdown of OR and NOT logic.

    • Supports any AND, OR, and NOT combination of multiple conditions.

  • Flexible and fast index management.

    • Create an inverted index when creating a table.

    • Add an inverted index to an existing table.

    • Delete an inverted index from a table.

Limitations

  • The FLOAT and DOUBLE floating-point data types do not support an inverted index due to precision issues. Instead, use the DECIMAL fixed-point data type, which supports an inverted index.

  • Some complex data types do not support an inverted index, including MAP, STRUCT, JSON, HLL, BITMAP, QUANTILE_STATE, and AGG_STATE. To use an inverted index with JSON data, convert the column to the VARIANT data type.

  • You can create an inverted index on a field of a numeric type, but you cannot specify a parser, such as english, chinese, or unicode.

  • The DUPLICATE model and the UNIQUE model with Merge on Write enabled support an inverted index on any column. In contrast, the AGGREGATE model and the UNIQUE model with Merge on Write disabled support an inverted index only on a Key column. Because these models must read and merge all data, the system cannot use the index for pre-filtering.

Create an index

You can create an inverted index during table creation or on a column in an existing table.

Create index on table creation

This is a synchronous operation. Index creation completes when the table is successfully created.

Important

Inverted indexes have the following limitations in different data models:

  • For the aggregate key model, you can create an inverted index only on key columns.

  • For the unique key model, the Merge on Write feature must be enabled. Once enabled, you can create an inverted index on any column.

  • For the duplicate key model, you can create an inverted index on any column.

Syntax

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

Parameters

Table creation parameters

Parameter

Required

Description

db_name

No

The name of the database that will contain the table.

table_name

Yes

The name of the table to create.

column_definition_list

Yes

A list of column definitions. For more information, see CREATE-TABLE.

table_properties

Yes

The table properties, such as the data model, partitioning and bucketing. For more information, see data model.

index_definition_list

No

A list of index definitions.

index_definition_list

You can define one or more indexes when you create a table. Use the following format: index_definition[, index_definition][, index_definition]....

index_definition

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

Parameters

Required parameters

Parameter

Description

index_name

The name of the index.

column_name

The name of the column to index.

index_type

The index type. Set this to USING INVERTED.

Optional parameters
Properties

The PROPERTIES clause specifies tokenization options for the index. It consists of one or more comma-separated key-value pairs in the format "<key>" = "<value>". If you are unsure how a given text will be tokenized, use the TOKENIZE function to view the output. For more information, see Tokenization functions.

Key

Value

parser

Specifies the tokenizer. If this property is omitted, no tokenization occurs. The parser property is not supported for numeric data types.

  • english: The English tokenizer. Ideal for English text, this high-performance tokenizer separates words based on spaces and punctuation.

  • chinese: The Chinese tokenizer. Suitable for text that contains Chinese characters. Its performance is lower than the English tokenizer.

  • unicode: The Unicode tokenizer. Suitable for mixed-language text, such as Chinese and English. It can tokenize email prefixes and suffixes, IP addresses, and alphanumeric strings. It also tokenizes Chinese text character by character.

parser_mode

Specifies the word tokenization mode, which determines the tokenization granularity.

All tokenizers use the coarse_grained mode by default. This mode tends to segment text into longer words. For example, 'Wuhan City Yangtze River Bridge' is segmented into the two words 'Wuhan City' and 'Yangtze River Bridge'.

When parser=chinese is specified for the Chinese tokenizer, the fine_grained mode is also supported. This mode tends to tokenize text into shorter words. For example, 'Wuhan City Yangtze River Bridge' is tokenized into six tokens: 'Wuhan', 'Wuhan City', 'mayor', 'Yangtze River', 'Yangtze River Bridge', and 'Bridge'.

To learn more about how tokenization works, see Tokenization functions.

support_phrase

Specifies whether the index supports accelerated MATCH_PHRASE phrase queries. The default is false.

  • true: Enables support, which requires more storage space.

  • false: Disables support to save storage space. You can use MATCH_ALL to query for multiple terms.

char_filter

Pre-processes strings before tokenization. Currently, char_filter_type only supports char_replace.

char_replace replaces each character in char_filter_pattern with a corresponding character from char_filter_replacement.

  • char_filter_pattern: An array of characters to be replaced.

  • This property is optional and defaults to a single space character if omitted.

ignore_above

Specifies a length limit for non-tokenized string values (when no parser is specified).

  • The system does not index strings longer than the ignore_above value. For string arrays, this limit applies to each element.

  • Default: 256 (bytes).

lower_case

Specifies whether to convert tokenized terms to lowercase for case-insensitive matching.

  • true: Converts to lowercase.

  • false: Retains the original case.

stopwords

Specifies a list of stopwords, which affects the tokenizer's behavior.

  • The built-in list includes common, low-value words (such as is, the, and a) that the system ignores during indexing and querying.

  • none: Uses an empty stopwords list.

dict_compression

Specifies whether to enable Zstandard (ZSTD) dictionary compression for the inverted index's dictionary.

  • true: Enables dictionary compression.

  • false: (Default) Disables dictionary compression.

  • Recommendation: Enable this for large text or log workloads, or to reduce storage costs. It works best with inverted_index_storage_format = "V3" and can reduce storage by approximately 20% for large-scale text and log data.

Note

This parameter is supported only in versions 4.1.0 and later.

Comment

Parameter

Description

comment

A description of the index.

Example: Create a table with an index

-- Create a table and an inverted index named idx_comment on the comment column.
-- USING INVERTED sets the index type to inverted index.
-- PROPERTIES("parser" = "english") sets the tokenizer to "english". Other supported tokenizers include "chinese" for Chinese text and "unicode" for mixed-language text. If the "parser" property is omitted, no tokenization occurs.
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;

Add an index

This operation is an asynchronous operation. You can check the index creation progress by using SHOW ALTER TABLE COLUMN;.

Syntax

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

Parameters

The parameters are the same as those for creating a table.

Examples

Add an index without tokenization.

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

Add an index that uses english for tokenization.

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

View inverted indexes

View index change progress

Modifying an inverted index using the ALTER and DROP commands is an asynchronous process. To view its progress, use the following statement.

SHOW ALTER TABLE COLUMN;

View all inverted table indexes

Syntax

SHOW INDEXES FROM <table_name>;

Example

SHOW INDEXES FROM user_tb;

Drop an index

Dropping an index is an asynchronous process. To check the progress, see Query the information about inverted indexes.

Important

Dropping an index can decrease query performance. Proceed with caution.

Syntax

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

Example

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

Inverted index

Full-text search

Syntax

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

Parameters

Parameter

Required

Description

table_name

Yes

The name of the table.

column_name

Yes

The name of the column.

conditional_logic

Yes

A combination of search operators and logical operators.

Logical operators: AND, OR, and NOT.

Search operators:

  • MATCH_ALL: Returns rows that contain all specified keywords.

  • MATCH_ANY: Returns rows that contain any specified keywords.

  • MATCH_PHRASE: Returns rows that contain the exact phrase.

keywords

Yes

The search keywords.

Separate multiple keywords with spaces.

Example: keyword1 keyword2 keyword3.

Examples

-- Retrieve rows where logmsg contains keyword1.
SELECT * FROM log_tb WHERE logmsg MATCH_ANY 'keyword1';

-- Retrieve rows where logmsg contains keyword1 or keyword2.
SELECT * FROM log_tb WHERE logmsg MATCH_ANY 'keyword1 keyword2';

-- Retrieve rows where logmsg contains both keyword1 and keyword2.
SELECT * FROM log_tb WHERE logmsg MATCH_ALL 'keyword1 keyword2';

-- Retrieve rows where logmsg contains the exact phrase "keyword1 keyword2".
SELECT * FROM log_tb WHERE logmsg MATCH_PHRASE 'keyword1 keyword2';

Equality and range queries for numeric and date

The query syntax is standard SQL syntax.

Example

-- Equality, range, IN, and NOT IN queries
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');

Query performance comparison

This topic uses a hackernews dataset with 1 million rows to compare query performance with and without an inverted index.

Prerequisites

Step 1: Create a table.

  1. Create a database.

    CREATE DATABASE test_inverted_index;
  2. Switch to the created database.

    USE test_inverted_index;
  3. Create the target table.

    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;
    -- Creates a table and an inverted index named idx_comment on the comment column.
    -- USING INVERTED specifies that the index type is an inverted index.
    -- PROPERTIES("parser" = "english") specifies that the English tokenizer is used. You can also specify "chinese" for Chinese text or "unicode" for mixed-language text. If you do not specify the "parser" parameter, no tokenization is performed.

Step 2: Import data

  1. Download the data file.

    wget https://qa-build.oss-cn-beijing.aliyuncs.com/regression/index/hacknernews_1m.csv.gz
  2. Import the data using Stream Load.

    On the instance details page for ApsaraDB for SelectDB, you can view the endpoint host and port number of an ApsaraDB for SelectDB instance. For more information about Stream Load, see 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. Run a count() query to verify the data import.

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

Performance comparison

Note
  • Count results may differ between queries that use an inverted index with a tokenizer and those that do not. This is because the inverted index tokenizes the column data and normalizes the terms (for example, by converting them to lowercase), which can cause queries that use the index to match more rows.

  • The performance difference in some examples may not be significant because the dataset is small. The larger the dataset, the greater the performance improvement.

Full-text search
  • Count rows where the comment column contains OLAP.

    • Counting the number of rows in the comment column that contain OLAP by using the LIKE operator takes 0.18s.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%';
      +---------+
      | count() |
      +---------+
      |      34 |
      +---------+
      1 row in set (0.18 sec)
    • The MATCH_ANY full-text search based on an inverted index counts the number of rows in the comment column that contain OLAP in 0.02s. This is 9 times faster than using the LIKE operator.

      SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLAP';
      +---------+
      | count() |
      +---------+
      |      35 |
      +---------+
      1 row in set (0.02 sec)
  • Count rows where the comment column contains OLTP.

    • This operation counts the number of rows in the comment column that contain OLTP by using the LIKE operator and takes 0.07s.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      48 |
      +---------+
      1 row in set (0.07 sec)
    • The MATCH_ANY full-text search based on an inverted index counts the number of rows in the comment column that contain OLTP in 0.01s. This is 7 times faster than using the LIKE operator.

      SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLTP';
      +---------+
      | count() |
      +---------+
      |      51 |
      +---------+
      1 row in set (0.01 sec)
  • Count rows where the comment column contains both OLAP and OLTP.

    • Using LIKE, the query takes 0.13s.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' AND comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      14 |
      +---------+
      1 row in set (0.13 sec)
    • Using full-text search with MATCH_ALL, the query takes 0.01s, making it 13 times faster than using LIKE.

       SELECT count() FROM hackernews_1m WHERE comment MATCH_ALL 'OLAP OLTP';
      +---------+
      | count() |
      +---------+
      |      15 |
      +---------+
      1 row in set (0.01 sec)
  • Count rows where the comment column contains either OLAP or OLTP.

    • Using LIKE, the query takes 0.12s.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' OR comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      68 |
      +---------+
      1 row in set (0.12 sec)
    • Using full-text search with MATCH_ANY, the query takes 0.01s, making it 12 times faster than using LIKE.

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

Equality and range queries

  • Compare the performance of a range query on a DateTimeV2 column.

    1. Without an inverted index, a query to count rows where timestamp is greater than 2007-08-23 04:17:00 takes 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. Add an inverted index to the timestamp column.

      CREATE INDEX idx_timestamp ON hackernews_1m(timestamp) USING INVERTED;
      Query OK, 0 rows affected (0.03 sec)
    3. Check the index creation progress. The difference between FinishTime and CreateTime shows that creating the inverted index for 1 million rows on the timestamp column took only 1 second.

      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. After an inverted index is created, running the same query to count data where the timestamp column is greater than 2007-08-23 04:17:00 takes 0.01 seconds. This is an improvement of 2 seconds compared to the query speed without an inverted index.

      SELECT count() FROM hackernews_1m WHERE timestamp > '2007-08-23 04:17:00';
      +---------+
      | count() |
      +---------+
      |  999081 |
      +---------+
      1 row in set (0.01 sec)
  • Compare the performance of an equality query on a numeric column.

    1. Without an inverted index, a query to count rows where the parent column equals 11189 takes 0.01s.

      SELECT count() FROM hackernews_1m WHERE parent = 11189;
      +---------+
      | count() |
      +---------+
      |       2 |
      +---------+
      1 row in set (0.01 sec)
    2. Create an inverted index on the numeric parent column without a tokenizer.

      -- For numeric types, you do not need to specify a tokenizer when using INVERTED.
      -- ALTER TABLE ... ADD INDEX is an alternative syntax for creating an index.
      ALTER TABLE hackernews_1m ADD INDEX idx_parent(parent) USING INVERTED;
      Query OK, 0 rows affected (0.01 sec)
    3. Check the index creation progress.

      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. Run the same query again. The query time remains 0.01s, showing no significant change for this dataset.

      SELECT count() FROM hackernews_1m WHERE parent = 11189;
      +---------+
      | count() |
      +---------+
      |       2 |
      +---------+
      1 row in set (0.01 sec)
  • Compare the performance of an equality query on a string column.

    1. Without an inverted index, a query to count rows where the author column equals 'faster' takes 0.03s.

      SELECT count() FROM hackernews_1m WHERE author = 'faster';
      +---------+
      | count() |
      +---------+
      |      20 |
      +---------+
      1 row in set (0.03 sec)
    2. Create an inverted index on the author column without a tokenizer.

      -- In this example, only USING INVERTED is specified. The values in the author column are not tokenized, and each value is treated as a single term.
      ALTER TABLE hackernews_1m ADD INDEX idx_author(author) USING INVERTED;
      Query OK, 0 rows affected (0.01 sec)
    3. Check the index creation progress.

      -- It takes only 1.5s to incrementally create an index on the author column with 1 million rows of data.
      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. After creating the index, the query takes only 0.01s, making it 3 times faster.

      -- After the index is created, string equality matching is also significantly accelerated.
      SELECT count() FROM hackernews_1m WHERE author = 'faster';
      +---------+
      | count() |
      +---------+
      |      20 |
      +---------+
      1 row in set (0.01 sec)

Tokenize function

The TOKENIZE function breaks a text string into a sequence of terms. Tokenization is a core component for building and using an inverted index. The quality of tokenization directly impacts index performance.

To see how a text string is tokenized, use the TOKENIZE function to view the result. The TOKENIZE function has two main parameters: parser and parser_mode. The following table describes these parameters.

Parameter

Description

parser

Specifies the tokenizer to use. If this parameter is omitted, the function does not perform tokenization.

  • english: The English tokenizer. This is suitable for fields that contain English text. It tokenizes text based on spaces and punctuation and offers high performance.

  • chinese: The Chinese tokenizer. This is suitable for fields that contain Chinese text. It performs more slowly than the English tokenizer.

  • unicode: The mixed-language tokenizer. This is suitable for mixed-language text, such as Chinese and English. It tokenizes email prefixes and suffixes, IP addresses, and alphanumeric strings. It also tokenizes Chinese text character by character.

parser_mode

Specifies the tokenization mode, which determines the tokenization granularity.

All tokenizers use the coarse_grained mode by default. This mode tends to segment text into longer words. For example, the string '武汉市长江大桥' is segmented into the two words '武汉市' and '长江大桥'.

When parser=chinese is specified for the Chinese tokenizer, the fine_grained mode is also supported. The fine_grained mode tends to segment text into shorter words. For example, '武汉市长江大桥' is tokenized into six words: '武汉', '武汉市', '市长', '长江', '长江大桥', and '大桥'.

Examples:

-- English tokenization result.
SELECT TOKENIZE('I love CHINA','"parser"="english"');
+------------------------------------------------+
| tokenize('I love CHINA', '"parser"="english"') |
+------------------------------------------------+
| ["i", "love", "china"]                         |
+------------------------------------------------+
1 row in set (0.02 sec)

-- Fine-grained tokenization result from the Chinese tokenizer.
SELECT TOKENIZE('武汉长江大桥','"parser"="chinese","parser_mode"="fine_grained"');
+-----------------------------------------------------------------------------------+
| tokenize('武汉长江大桥', '"parser"="chinese","parser_mode"="fine_grained"')       |
+-----------------------------------------------------------------------------------+
| ["武汉", "武汉长江大桥", "长江", "长江大桥", "大桥"]                              |
+-----------------------------------------------------------------------------------+
1 row in set (0.02 sec)

-- Coarse-grained tokenization result from the Chinese tokenizer.
SELECT TOKENIZE('武汉市长江大桥','"parser"="chinese","parser_mode"="coarse_grained"');
+----------------------------------------------------------------------------------------+
| tokenize('武汉市长江大桥', '"parser"="chinese","parser_mode"="coarse_grained"')        |
+----------------------------------------------------------------------------------------+
| ["武汉市", "长江大桥"]                                                                 |
+----------------------------------------------------------------------------------------+
1 row in set (0.02 sec)

-- Mixed-language tokenization result.
SELECT TOKENIZE('I love CHINA 我爱我的祖国','"parser"="unicode"');
+-------------------------------------------------------------------+
| tokenize('I love CHINA 我爱我的祖国', '"parser"="unicode"')       |
+-------------------------------------------------------------------+
| ["i", "love", "china", "我", "爱", "我", "的", "祖", "国"]        |
+-------------------------------------------------------------------+
1 row in set (0.02 sec)