All Products
Search
Document Center

PolarDB:IMCI Full-text Index User Guide

Last Updated:Aug 04, 2026

This document describes how to build and use full-text indexes on the In-Memory Column Index (IMCI) of PolarDB for MySQL. By configuring inverted indexes through column-level COMMENT, you can leverage MATCH...AGAINST syntax or automatically optimized LIKE queries to achieve millisecond-level fuzzy search. This feature is based on IMCI's inverted index and term matching mechanism. For detailed principles, see An analysis of the full-text search feature in IMCI.

Version requirements

Your cluster version must meet the following requirements:

  • MySQL 8.0.1, and the minor version must be 8.0.1.1.52 or later.

  • MySQL 8.0.2, and the minor version must be 8.0.2.2.32 or later.

Syntax

PolarDB IMCI allows you to create, modify, or delete inverted indexes by specifying the column comment when creating a table or modifying the column comment through DDL.

Syntax

  • Define a full-text index when creating a table:

    CREATE TABLE table_name (
        column_name Data_Type COMMENT "imci_fts(type=VALUE [,KEY=VALUE])"
    ) COMMENT 'columnar=1';
  • Use ALTER to modify a column to add or modify an index:

    ALTER TABLE table_name MODIFY column_name Data_Type COMMENT "imci_fts(type=VALUE [,KEY=VALUE])";
    Important

    Modifying COMMENT may trigger a rebuild of the inverted index. For large tables, we recommend that you perform this operation during off-peak hours.

  • Use ALTER to modify a column to delete an index:

    ALTER TABLE table_name MODIFY column_name Data_Type COMMENT 'imci_fts(enable=0)';

Parameters

You must set COMMENT to 'columnar=1' at the table level to create an IMCI column store table. Full-text indexes are configured through the column's COMMENT in the format imci_fts(TYPE=VALUE[, KEY=VALUE]...), where TYPE is required and KEY is optional. Multiple KEY pairs are separated by commas.

  • Tokenizer type (the type parameter):

    Tokenizer

    type value

    Description

    token

    0 (default)

    Splits text by non-alphanumeric characters such as spaces and punctuation. Suitable for English or formatted text.

    ngram

    1

    Splits text into fixed-length character chunks (controlled by the len parameter). Suitable for fuzzy matching across any language.

    jieba

    2

    A dictionary-based Chinese tokenizer. Suitable for semantic Chinese search.

    ik

    3

    Another widely used Chinese tokenizer.

    json

    4

    Extracts content from JSON fields using JSONPath expressions (requires the expr parameter) to build indexes.

    whole

    5

    Does not split text. The entire column is treated as a single term. Primarily used for accelerating equality queries (such as = or IN).

    mysql ngram

    6

    MySQL-compatible ngram tokenizer.

  • Configuration parameters (KEY-VALUE):

    Parameter (KEY)

    Default

    Description

    Applicable tokenizer types (type)

    enable

    1

    • 1: Create an inverted index (default)

    • 0: Delete the inverted index

    All

    type

    0

    Specifies the tokenizer type (see the table above)

    All

    len

    -

    The token length for the ngram tokenizer. Valid range: [1, 256)

    type=1 (ngram), type=6 (mysql ngram)

    mode

    0

    Tokenizer mode:

    • jieba (type=2):

      • 0: Accurate mode (default)

      • 1: Full mode

      • 2: Search engine mode

    • ik (type=3):

      • 0: Smart mode (default)

      • 1: Most fine-grained mode

    • json (type=4):

      • 0: Legacy array mode (default)

      • 1: Array mode

      • 2: Key-value mode, such as "*.id", "[*].id", etc.

    type=2, 3, 4

    score

    0

    Whether to support sorting:

    • 0: Disable term frequency (TF) and document frequency (DF) generation, ignore sorting (default)

    • 1: Enable relevance score sorting for MATCH ... AGAINST

    All

    seg_size

    0

    Specifies the inverted index segment size:

    • 0: Use the value of the imci_fts_build_segment_size system variable

    • Other values: Specify an exact segment size

    All

    pack_cnt_min

    0

    Minimum number of data units for inverted index builds:

    • 0: Use the value of the imci_fts_build_packcnt_min system variable

    • Other values: Specify an exact value

    All

    pack_cnt_max

    0

    Maximum number of data units for inverted index builds:

    • 0: Use the value of the imci_fts_build_packcnt_max system variable

    • Other values: Specify an exact value

    All

    stop_word

    0

    Whether to support stop words:

    • 0: Not supported (default)

    • 1: Supported

    All

    case_sensitive

    0

    Whether the matching is case-sensitive:

    • 0: Case-insensitive (default)

    • 1: Case-sensitive

    • 2: Determined by the column's collate setting (MySQL-compatible mode)

    • 3: Fully determined by the column's collate setting (entirely controlled by collate)

    All

    phrase

    0

    Whether to record positional information for phrase queries:

    • 0: Do not record positional information (default)

    • 1: Record positional information

    All

    synonym

    0

    Whether to support synonyms:

    • 0: Not supported (default)

    • 1: Supported, query mode

    • 2: Supported, index mode (requires rebuilding the inverted index)

    All

Examples

1: Create a full-text index

Create a full-text index on the column that requires text search, and choose a tokenizer based on your business needs.

  1. Create a test table: Create a table with a column store index.

    CREATE TABLE t1 (
        id INT PRIMARY KEY,
        title VARCHAR(32) COMMENT "imci_fts(type=2)"
    )CHARSET utf8mb4 COMMENT 'columnar=1';
  2. (Optional) Modify the full-text index: Use the ALTER TABLE statement to add a full-text index to the title column and specify the search engine mode of the jieba tokenizer.

    ALTER TABLE t1 MODIFY title VARCHAR(32) COMMENT "imci_fts(type=2,mode=0)";
  3. (Optional) Verify tokenization results: Before choosing a tokenizer, you can use the dbms_imci.fts_tokenize function to preview how different tokenizers process text.

    CALL dbms_imci.fts_tokenize("I am PolarDB");
    -- Result: ["i", "am", "polardb"]  
    
    CALL dbms_imci.fts_tokenize("I am PolarDB", "type=1");
    -- Result: ["i ", " a", "am", "m ", " p", "po", "ol", "ar", "rd", "db"]
    
    CALL dbms_imci.fts_tokenize("I am PolarDB", "type=2");
    -- Result: ["PolarDB"]
    
    CALL dbms_imci.fts_tokenize("I am PolarDB", "type=2,mode=1");
    -- Result: ["polardb"]

2: Run full-text search queries

After the index is created, IMCI builds it in the background. Once the build is complete, you can run text queries using MATCH...AGAINST or optimized LIKE statements.

  1. Use MATCH...AGAINST queries:

    -- Insert sample data
    INSERT INTO t1 VALUES 
    (16, 'polarDB full-text index feature title'), 
    (17, 'database title performance optimization');
    -- Find rows where the title column contains "title"
    SELECT * FROM t1 WHERE MATCH(title) AGAINST("title");

    Use EXPLAIN to view the execution plan. If the FtsTableScan operator appears, the query has hit the full-text index.

    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%")             |
    +----+------------------------+------+-----------------------------------------------------------------+

    Fallback indicates that for incremental data not yet indexed, the system automatically uses LIKE supplementary scans to ensure result completeness.

  2. Accelerate LIKE queries: To be compatible with existing application code, IMCI supports automatically converting specific LIKE queries to MATCH...AGAINST for acceleration.

    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%")             |
    +----+------------------------+------+-----------------------------------------------------------------+

    The execution plan also displays the FtsTableScan operator, confirming that the LIKE query has been successfully accelerated.

  3. MATCH to LIKE conversion: When no full-text index exists, to ensure the query still runs correctly while leveraging existing indexes as much as possible, IMCI may convert MATCH to LIKE, and the execution plan shows a full table scan.

    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: Manage and monitor indexes

Query the build status and metadata of indexes, and delete indexes when they are no longer needed.

  1. Monitor index build progress and status:

    -- View all inverted indexes
    SHOW imci indexes fulltext;
    SELECT * FROM information_schema.imci_fts_indexes;
    
    -- View a specific inverted index
    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]';
    
    -- View metadata of a specific inverted index
    SELECT * FROM information_schema.imci_fts_index_metas 
    WHERE schema_name='[db_name]' AND table_name='[table_name]' AND column_name='[column_name]';
    
    -- View segment data of a specific inverted index
    SELECT * FROM information_schema.imci_fts_index_segs 
    WHERE schema_name='[db_name]' AND table_name='[table_name]' AND column_name='[column_name]';
    
    -- View column store data of a specific inverted index
    SELECT * FROM information_schema.imci_fts_index_packs 
    WHERE schema_name='[db_name]' AND table_name='[table_name]' AND column_name='[column_name]';
  2. Delete a full-text index: If you no longer need a full-text index on a column, you can delete it by modifying the column's COMMENT.

    ALTER TABLE t1 MODIFY title VARCHAR(255) COMMENT 'imci_fts(enable=0)';

4: Core system variables

Parameter

Scope

Description

imci_enable_fts

Global

Whether to allow creating inverted indexes on column store nodes.

  • ON (default): Enabled. Supports string and JSON data types.

  • OFF: Disabled.

imci_enable_fts_query

Global / Session

Whether to allow using inverted indexes on column store nodes.

  • ON: Enabled.

  • OFF (default): Disabled.

imci_fts_build_pack_cnt_min

Global

Minimum number of column store data blocks per inverted index during index builds.

Valid range: 0-8192. Default value: 8. A value of 0 means the build is temporarily paused.

imci_fts_build_pack_cnt_max

Global

Maximum number of column store data blocks per inverted index during index builds.

Valid range: 0-8192. Default value: 128.

imci_fts_build_segment_size

Global

Segment size for each inverted index during index builds.

Valid range: 0-4294967295. Default value: 536870912 (512 MB), in bytes.

imci_fts_lru_cache_capacity

Global

Cache space for inverted index dictionaries.

Valid range: [DBNodeClassMemory*1/10~DBNodeClassMemory*1/2]. Default value: [DBNodeClassMemory*10/100].

imci_enable_fts_pruner

Global / Session

Whether to enable pre-filtering optimization for inverted indexes.

  • ON (default): Enabled.

  • OFF: Disabled.

imci_convert_like_to_match

Global / Session

Whether to enable converting LIKE to MATCH and using inverted indexes for acceleration.

  • ON: Enabled.

  • OFF (default): Disabled.

  • ONLY_MATCH: Enabled and the LIKE expression is ignored;

imci_enable_query_fts_like

Global / Session

Whether to enable converting MATCH to LIKE.

  • ON: Enabled.

  • OFF (default): Disabled.

imci_enable_match_expr_fallback

Global / Session

Whether to enable queries on incremental data that has not yet been indexed by the inverted index.

  • ON (default): Enabled.

  • OFF: Disabled.

imci_fts_build_fts_cnt

Global

Number of concurrent inverted index build threads.

Valid range: 0-512. Default value: 4.

Note

This parameter is only applicable to the following versions:

  • MySQL 8.0.1, and the minor version must be 8.0.1.1.54 or later.

  • MySQL 8.0.2, and the minor version must be 8.0.2.2.34 or later.

imci_fts_user_dict_table

Global

Configures the custom dictionary for full-text indexes. Format: database_name/table_name.

Note

This parameter is only applicable to the following versions:

  • MySQL 8.0.1, and the minor version must be 8.0.1.1.54 or later.

  • MySQL 8.0.2, and the minor version must be 8.0.2.2.34 or later.

imci_fts_user_dict_update

Global

Whether to reload the custom dictionary specified by imci_fts_user_dict_table.

  • ON (default): Enabled.

  • OFF: Disabled.

Note

This parameter is only applicable to the following versions:

  • MySQL 8.0.1, and the minor version must be 8.0.1.1.54 or later.

  • MySQL 8.0.2, and the minor version must be 8.0.2.2.34 or later.

imci_convert_json_overlap_to_match

Global/Session

Controls whether to enable json_overlaps acceleration using the JSON index.

  • ON: Enabled.

  • OFF (default): Disabled.

imci_convert_json_contains_to_match

Global/Session

Controls whether to enable json_contains acceleration using the JSON index.

  • ON: Enabled.

  • OFF (default): Disabled.

imci_convert_json_extract_to_match

Global/Session

Controls whether to enable json_extract acceleration using the JSON index.

  • ON: Enabled.

  • OFF (default): Disabled.

imci_convert_equal_to_match

Global/Session

Controls whether to enable = expression acceleration using the equality index.

  • ON: Enabled.

  • OFF (default): Disabled.

imci_convert_in_to_match

Global/Session

Controls whether to enable IN expression acceleration using the equality index.

  • ON: Enabled.

  • OFF (default): Disabled.

imci_convert_ne_to_match

Global/Session

Controls whether to enable != expression acceleration using the equality index.

  • ON: Enabled.

  • OFF (default): Disabled.

imci_enable_fts_synonym

Global / Session

Whether to support synonyms.

  • ON (default): Enabled.

  • OFF: Disabled.

imci_enable_fts_parse_term_with_and

Global / Session

Whether to use AND evaluation after tokenizing the query string.

  • ON (default): Enabled.

  • OFF: Disabled, OR evaluation.

imci_enable_fts_parse_term_with_phrase

Global / Session

Whether to enforce strict positional matching for tokenized query strings in BOOLEAN MODE.

  • ON: Enabled.

  • OFF (default): Disabled.

imci_fts_stop_word_table

Global

Configures the custom stop words for full-text indexes. Format: database_name/table_name. For more information, see Custom stop words.

imci_fts_stop_word_update

Global

Whether to reload the custom stop words specified by imci_fts_stop_word_table.

  • ON (default): Enabled.

  • OFF: Disabled.

imci_fts_synonym_table

Global

Configures the custom synonyms for full-text indexes. Format: database_name/table_name. For more information, see Custom synonyms.

imci_fts_synonym_update

Global

Whether to reload the custom synonyms specified by imci_fts_synonym_table.

  • ON (default): Enabled.

  • OFF: Disabled.

Important

Parameters with a GLOBAL scope cannot be directly modified from the command line. They can only be changed through the console. When executed from the command line, the default scope is SESSION.

Custom dictionary

The IMCI full-text index feature supports custom dictionaries through custom tables to achieve tokenization results that better match your business scenarios.

Create a custom dictionary table

  1. First, define a table with the same structure as the my_fts_dict table. Column names must match those of the my_fts_dict table.

    • type: Tokenizer type. Only the jieba tokenizer (type 2) and the IK tokenizer (type 3) are supported.

    • word: The dictionary word.

    • is_added: Add the word to the custom dictionary (value 1) or remove it (value 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';
  2. The custom dictionary itself is an InnoDB table. Read and write operations are the same as those for a regular table.

    1. Add a word:

      INSERT INTO my_fts_dict VALUES(2, "PolarDB", 1)
    2. Remove a word:

      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";

Configure the custom dictionary

  • After creating the custom dictionary table, configure the imci_fts_user_dict_table parameter. For example, test/my_fts_dict'.

    SET GLOBAL imci_fts_user_dict_table = 'test/my_fts_dict';
  • If imci_fts_user_dict_table is already set, you can also set imci_fts_user_dict_update to ON to trigger a reload of the custom dictionary specified by imci_fts_user_dict_table.

    SET GLOBAL imci_fts_user_dict_update = ON;
    Note

    The new custom dictionary only takes effect on subsequently built inverted indexes. To apply it to existing inverted indexes, you must rebuild the inverted indexes.

Custom synonyms

The IMCI full-text index feature supports custom synonyms through custom tables.

Create a custom synonym table

First, define a table with the same structure as the my_synonym_dict table. Column names must match those of the my_synonym_dict table.

  • word: The synonym list. Different words are separated by commas.

  • type: The synonym type.

    • 0 indicates that all words in the list are synonyms of each other. For example, "db,database,polardb" means "db" <=> "database" <=> "polardb". When you search for "db", "database", or "polardb", all data matching "db", "database", and "polardb" is returned.

    • 1 indicates that the first word in the list is the primary term and the others are its synonyms. For example, "db,database,polardb" means "db" => "database", "polardb". When you search for "db", all data matching "db", "database", and "polardb" is returned. However, when you search for "database", only data matching "database" is returned.

CREATE TABLE my_synonym_dict (
  `word` VARCHAR(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'comma-separated synonyms',
  `type` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '0 for equivalent, 1 for mapping'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='imci fts synonym';

The custom synonym table itself is an InnoDB table. Read and write operations are the same as those for a regular table.

  • Add a word:

    INSERT INTO my_synonym_dict VALUES("db,database,polardb", 0);
    INSERT INTO my_synonym_dict VALUES("imci,clickhouse,duckdb", 1);
  • Remove a word:

    DELETE FROM my_synonym_dict WHERE type=1 AND word = "imci,clickhouse,duckdb";

Configure custom synonyms

After creating the custom synonym table, configure the imci_fts_synonym_table parameter. For example, test/my_synonym_dict, where test is the database name and my_synonym_dict is the table name.

SET GLOBAL imci_fts_synonym_table = 'test/my_synonym_dict';

If imci_fts_synonym_table is already set, you can also set imci_fts_synonym_update to ON to trigger a reload of the custom synonyms specified by imci_fts_synonym_table.

SET GLOBAL imci_fts_synonym_update = ON;
Note

If synonym is set to index mode (e.g., COMMENT "imci_fts(type=0 synonym=1)"), updated synonyms only take effect on newly indexed data. To apply the changes to all data, you must rebuild the full-text index.

Custom stop words

The IMCI full-text index feature supports custom stop words through custom tables.

Create a custom stop word table

First, define a table with the same structure as the my_stop_words table. Column names must match those of my_stop_words.

  • word: The stop word.

  • is_added: Add the word to the custom dictionary (value 1) or remove it (value 0).

CREATE TABLE my_stop_words (
  `word` VARCHAR(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT 'stop word',
  `is_added` INT UNSIGNED NOT NULL DEFAULT 1 COMMENT '1 for add, 0 for delete'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='imci fts stop word';

The custom stop word table itself is an InnoDB table. Read and write operations are the same as those for a regular table.

  • Add a word:

    INSERT INTO my_stop_words VALUES("am", 1);
    INSERT INTO my_stop_words VALUES("chinese", 1);
  • Remove a word:

    INSERT INTO my_stop_words(word, is_added) VALUES("chinese", 0);
    -- or
    DELETE FROM my_stop_words WHERE is_added=1 AND word = "chinese";

Configure custom stop words

After creating the custom stop word table, configure the imci_fts_stop_word_table parameter. For example, test/my_stop_words, where test is the database name and my_stop_words is the table name.

SET GLOBAL imci_fts_stop_word_table = 'test/my_stop_words';

If imci_fts_stop_word_table is already set, you can also set imci_fts_stop_word_update to ON to trigger a reload of the custom stop words specified by imci_fts_stop_word_table.

SET GLOBAL imci_fts_stop_word_update = ON;
Note

The new custom stop words only take effect on subsequently built inverted indexes. To apply them to existing inverted indexes, you must rebuild the inverted indexes.

FAQ

Q1: How do I choose the right tokenizer?

  • English or formatted text: Use the default type=0 (token), which splits by spaces and punctuation.

  • Precise Chinese search: Use the default mode of type=2 (jieba) or type=3 (ik).

  • JSON content search: Use type=4 (json) with the expr parameter to specify the JSON path to index.

  • You can preview how different tokenizers process text using the dbms_imci.fts_tokenize function.

Q2: Why isn't my query using the full-text index?

  1. Make sure SET imci_enable_fts_query = ON; has been executed. This is the most common cause.

  2. Check the EXPLAIN output and verify whether the FtsTableScan operator is present. If not, the query pattern may not match the index, or the system may have determined that a full table scan has a lower cost.

Q3: What is the difference between LIKE queries and MATCH...AGAINST?

  • LIKE '%keyword%' without a full-text index causes a full table scan, resulting in poor performance. Even when accelerated by IMCI, its functionality is relatively limited.

  • MATCH...AGAINST is syntax specifically designed for full-text search. It delivers high performance and will support more advanced features such as Boolean queries and relevance scoring in the future. We recommend using MATCH...AGAINST for new applications.