Todos os produtos
Search
Central de documentação

ApsaraDB for SelectDB:Índice invertido

Última atualização: Jun 29, 2026

O índice invertido é uma técnica comum de indexação em recuperação de informações. Ele funciona tokenizando texto em termos para construir um índice, permitindo recuperar rapidamente documentos que contêm esses termos.ApsaraDB for SelectDB oferece suporte a índices invertidos. Use esse recurso para realizar buscas de texto completo em tipos de dados de texto e executar consultas de igualdade e intervalo em tipos numéricos e de data, filtrando grandes conjuntos de dados com agilidade. Este tópico descreve o recurso de índice invertido no ApsaraDB for SelectDB, incluindo como criá-lo e utilizá-lo.

Como funciona

No Alibaba Cloud SelectDB, o índice invertido trata cada linha da tabela como um documento e cada coluna como um campo. Isso permite localizar rapidamente as linhas que contêm uma palavra-chave específica, melhorando o desempenho de consultas que utilizam a cláusula WHERE.

Diferentemente de um índice comum, o índice invertido é armazenado em um arquivo invertido separado. Esse arquivo é mapeado logicamente para o arquivo de segmento, mas não se integra a ele. Essa abordagem evita a reescrita do arquivo de segmento durante atualizações e exclusões de índice, reduzindo significativamente a sobrecarga de processamento.

Cenários

  • Acelera a busca de texto completo em tipos de dados string.

  • Acelera a filtragem com =, !=, >, >=, <, <= para tipos string, numéricos e datetime.

Benefícios

  • Suporte abrangente a operadores lógicos.

    • Adição de suporte para pushdown de índice com lógica OR and NOT.

    • Compatibilidade com qualquer combinação de múltiplas condições usando AND, OR, and NOT.

  • Gerenciamento de índice flexível e rápido.

    • Crie um índice invertido durante a criação da tabela.

    • Adicione um índice invertido a uma tabela existente.

    • Exclua um índice invertido de uma tabela.

Limitações

  • Os tipos de dados de ponto flutuante FLOAT e DOUBLE não oferecem suporte a índice invertido devido a questões de precisão. Em vez disso, utilize o tipo de dados de ponto fixo DECIMAL, que possui suporte a índice invertido.

  • Alguns tipos de dados complexos não suportam índice invertido, incluindo MAP, STRUCT, JSON, HLL, BITMAP, QUANTILE_STATE e AGG_STATE. Para usar um índice invertido com dados JSON, converta a coluna para o tipo de dados VARIANT.

  • É possível criar um índice invertido em um campo de tipo numérico, mas não é permitido especificar um parser, como english, chinese ou unicode.

  • O modelo DUPLICATE e o modelo UNIQUE com Merge on Write ativado suportam índice invertido em qualquer coluna. Por outro lado, o modelo AGGREGATE e o modelo UNIQUE com Merge on Write desativado suportam índice invertido apenas em colunas Key. Como esses modelos precisam ler e mesclar todos os dados, o sistema não consegue utilizar o índice para pré-filtragem.

Criar um índice

Crie um índice invertido durante a criação da tabela ou em uma coluna de uma tabela existente.

Criar índice na criação da tabela

Esta é uma operação síncrona. A criação do índice é concluída quando a tabela é criada com sucesso.

Importante

Os índices invertidos apresentam as seguintes limitações nos diferentes modelos de dados:

  • No modelo de chave agregada, só é possível criar um índice invertido em colunas de chave.

  • No modelo de chave única, o recurso Merge on Write deve estar ativado. Após a ativação, crie um índice invertido em qualquer coluna.

  • No modelo de chave duplicada, crie um índice invertido em qualquer coluna.

Sintaxe

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

Parâmetros

Parâmetros de criação de tabela

Parameter

Required

Description

db_name

No

Nome do banco de dados que conterá a tabela.

table_name

Yes

Nome da tabela a ser criada.

column_definition_list

Yes

Lista de definições de colunas. Para mais informações, consulte CREATE-TABLE.

table_properties

Yes

Propriedades da tabela, como modelo de dados, particionamento e bucketing. Para mais informações, consulte modelo de dados.

index_definition_list

No

Lista de definições de índices.

index_definition_list

Defina um ou mais índices ao criar uma tabela. Utilize o seguinte formato: index_definition[, index_definition][, index_definition]....

index_definition

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

Parâmetros

Parâmetros obrigatórios

Parameter

Description

index_name

Nome do índice.

column_name

Nome da coluna a ser indexada.

index_type

Tipo do índice. Defina como USING INVERTED.

Parâmetros opcionais

Properties

A cláusula PROPERTIES especifica as opções de tokenização para o índice. Ela consiste em um ou mais pares chave-valor separados por vírgulas no formato "<key>" = "<value>". Caso tenha dúvidas sobre como um determinado texto será tokenizado, utilize a função TOKENIZE para visualizar a saída. Para mais informações, consulte Funções de tokenização.

Key

Value

parser

Especifica o tokenizador. Se esta propriedade for omitida, nenhuma tokenização ocorrerá. A propriedade parser não é suportada para tipos de dados numéricos.

  • english: Tokenizador para inglês. Ideal para textos em inglês, este tokenizador de alto desempenho separa palavras com base em espaços e pontuação.

  • chinese: Tokenizador para chinês. Adequado para textos que contêm caracteres chineses. Seu desempenho é inferior ao do tokenizador de inglês.

  • unicode: Tokenizador Unicode. Adequado para textos com idiomas mistos, como chinês e inglês. Consegue tokenizar prefixos e sufixos de e-mail, endereços IP e strings alfanuméricas. Também tokeniza texto chinês caractere por caractere.

parser_mode

Especifica o modo de tokenização de palavras, que determina a granularidade da tokenização.

Todos os tokenizadores usam o modo coarse_grained por padrão. Esse modo tende a segmentar o texto em palavras mais longas. Por exemplo, 'Wuhan City Yangtze River Bridge' é segmentado nas duas palavras 'Wuhan City' e 'Yangtze River Bridge'.

Quando parser=chinese é especificado para o tokenizador chinês, o modo fine_grained também é suportado. Esse modo tende a tokenizar o texto em palavras mais curtas. Por exemplo, 'Wuhan City Yangtze River Bridge' é tokenizado em seis tokens: 'Wuhan', 'Wuhan City', 'mayor', 'Yangtze River', 'Yangtze River Bridge' e 'Bridge'.

Para saber mais sobre o funcionamento da tokenização, consulte Funções de tokenização.

support_phrase

Especifica se o índice suporta consultas de frase MATCH_PHRASE aceleradas. O padrão é false.

  • true: Ativa o suporte, o que requer mais espaço de armazenamento.

  • false: Desativa o suporte para economizar espaço de armazenamento. Use MATCH_ALL para consultar múltiplos termos.

char_filter

Pré-processa strings antes da tokenização. Atualmente, char_filter_type suporta apenas char_replace.

char_replace substitui cada caractere em char_filter_pattern por um caractere correspondente de char_filter_replacement.

  • char_filter_pattern: Um array de caracteres a serem substituídos.

  • Esta propriedade é opcional e assume como padrão um único caractere de espaço se omitida.

ignore_above

Especifica um limite de comprimento para valores de string não tokenizados (quando nenhum parser é especificado).

  • O sistema não indexa strings maiores que o valor de ignore_above. Para arrays de strings, esse limite se aplica a cada elemento.

  • Padrão: 256 (bytes).

lower_case

Especifica se os termos tokenizados devem ser convertidos para minúsculas para correspondência sem distinção entre maiúsculas e minúsculas.

  • true: Converte para minúsculas.

  • false: Mantém a caixa original.

stopwords

Especifica uma lista de stopwords, o que afeta o comportamento do tokenizador.

  • A lista integrada inclui palavras comuns de baixo valor (como is, the e a) que o sistema ignora durante a indexação e consulta.

  • none: Usa uma lista vazia de stopwords.

dict_compression

Especifica se a compressão de dicionário Zstandard (ZSTD) deve ser ativada para o dicionário do índice invertido.

  • true: Ativa a compressão de dicionário.

  • false: (Padrão) Desativa a compressão de dicionário.

  • Recomendação: Ative esta opção para cargas de trabalho de texto grande ou logs, ou para reduzir custos de armazenamento. Funciona melhor com inverted_index_storage_format = "V3" e pode reduzir o armazenamento em aproximadamente 20% para dados de texto e log em grande escala.

Nota

Este parâmetro é suportado apenas nas versões 4.1.0 e posteriores.

Comment

Parameter

Description

comment

Descrição do índice.

Exemplo: Criar uma tabela com um índice

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

Adicionar um índice

Esta é uma operação assíncrona. Verifique o progresso da criação do índice usando SHOW ALTER TABLE COLUMN;.

Sintaxe

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

Parâmetros

Os parâmetros são os mesmos utilizados na criação da tabela.

Exemplos

Adicione um índice sem tokenização.

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

Adicione um índice que utiliza english para tokenização.

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

Visualizar índices invertidos

Visualizar progresso de alteração do índice

A modificação de um índice invertido usando os comandos ALTER e DROP é um processo assíncrono. Para acompanhar o progresso, execute a seguinte instrução.

SHOW ALTER TABLE COLUMN;

Visualizar todos os índices invertidos da tabela

Sintaxe

SHOW INDEXES FROM <table_name>;

Exemplo

SHOW INDEXES FROM user_tb;

Excluir um índice

A exclusão de um índice é um processo assíncrono. Para verificar o progresso, consulte Consultar informações sobre índices invertidos.

Importante

Excluir um índice pode reduzir o desempenho das consultas. Proceda com cautela.

Sintaxe

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

Exemplo

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

Índice invertido

Busca de texto completo

Sintaxe

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

Parâmetros

Parameter

Required

Description

table_name

Yes

Nome da tabela.

column_name

Yes

Nome da coluna.

conditional_logic

Yes

Combinação de operadores de busca e operadores lógicos.

Operadores lógicos: AND, OR, and NOT.

Operadores de busca:

  • MATCH_ALL: Retorna linhas que contêm todas as palavras-chave especificadas.

  • MATCH_ANY: Retorna linhas que contêm qualquer uma das palavras-chave especificadas.

  • MATCH_PHRASE: Retorna linhas que contêm a frase exata.

keywords

Yes

Palavras-chave de busca.

Separe múltiplas palavras-chave com espaços.

Exemplo: keyword1 keyword2 keyword3.

Exemplos

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

Consultas de igualdade e intervalo para numéricos e datas

A sintaxe de consulta segue o padrão SQL.

Exemplo

-- 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');

Comparação de desempenho de consultas

Este tópico utiliza um conjunto de dados hackernews com 1 milhão de linhas para comparar o desempenho de consultas com e sem índice invertido.

Pré-requisitos

Passo 1: Crie uma tabela.

  1. Crie um banco de dados.

    CREATE DATABASE test_inverted_index;
  2. Mude para o banco de dados criado.

    USE test_inverted_index;
  3. Crie a tabela de destino.

    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.

Passo 2: Importe os dados

  1. Baixe o arquivo de dados.

    wget https://qa-build.oss-cn-beijing.aliyuncs.com/regression/index/hacknernews_1m.csv.gz
  2. Importe os dados usando Stream Load.

    Na página de detalhes da instância do ApsaraDB for SelectDB, visualize o host do endpoint e o número da porta de uma instância do ApsaraDB for SelectDB. Para mais informações sobre Stream Load, consulte 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. Execute uma consulta count() para verificar a importação dos dados.

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

Comparação de desempenho

Nota
  • Os resultados de contagem podem diferir entre consultas que usam um índice invertido com tokenizador e aquelas que não usam. Isso ocorre porque o índice invertido tokeniza os dados da coluna e normaliza os termos (por exemplo, convertendo-os para minúsculas), o que pode fazer com que as consultas que usam o índice correspondam a mais linhas.

  • A diferença de desempenho em alguns exemplos pode não ser significativa porque o conjunto de dados é pequeno. Quanto maior o conjunto de dados, maior a melhoria de desempenho.

Busca de texto completo

  • Conte as linhas onde a coluna comment contém OLAP.

    • A contagem do número de linhas na coluna comment que contêm OLAP usando o operador LIKE leva 0,18s.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%';
      +---------+
      | count() |
      +---------+
      |      34 |
      +---------+
      1 row in set (0.18 sec)
    • A busca de texto completo MATCH_ANY baseada em índice invertido conta o número de linhas na coluna comment que contêm OLAP em 0,02s. Isso é 9 vezes mais rápido do que usar o operador LIKE.

      SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLAP';
      +---------+
      | count() |
      +---------+
      |      35 |
      +---------+
      1 row in set (0.02 sec)
  • Conte as linhas onde a coluna comment contém OLTP.

    • Esta operação conta o número de linhas na coluna comment que contêm OLTP usando o operador LIKE e leva 0,07s.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      48 |
      +---------+
      1 row in set (0.07 sec)
    • A busca de texto completo MATCH_ANY baseada em índice invertido conta o número de linhas na coluna comment que contêm OLTP em 0,01s. Isso é 7 vezes mais rápido do que usar o operador LIKE.

      SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLTP';
      +---------+
      | count() |
      +---------+
      |      51 |
      +---------+
      1 row in set (0.01 sec)
  • Conte as linhas onde a coluna comment contém tanto OLAP quanto OLTP.

    • Usando LIKE, a consulta leva 0,13s.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' AND comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      14 |
      +---------+
      1 row in set (0.13 sec)
    • Usando busca de texto completo com MATCH_ALL, a consulta leva 0,01s, tornando-a 13 vezes mais rápida do que usar LIKE.

       SELECT count() FROM hackernews_1m WHERE comment MATCH_ALL 'OLAP OLTP';
      +---------+
      | count() |
      +---------+
      |      15 |
      +---------+
      1 row in set (0.01 sec)
  • Conte as linhas onde a coluna comment contém OLAP ou OLTP.

    • Usando LIKE, a consulta leva 0,12s.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' OR comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      68 |
      +---------+
      1 row in set (0.12 sec)
    • Usando busca de texto completo com MATCH_ANY, a consulta leva 0,01s, tornando-a 12 vezes mais rápida do que usar LIKE.

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

Consultas de igualdade e intervalo

  • Compare o desempenho de uma consulta de intervalo em uma coluna DateTimeV2.

    1. Sem um índice invertido, uma consulta para contar linhas onde timestamp é maior que 2007-08-23 04:17:00 leva 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. Adicione um índice invertido à coluna timestamp.

      CREATE INDEX idx_timestamp ON hackernews_1m(timestamp) USING INVERTED;
      Query OK, 0 rows affected (0.03 sec)
    3. Verifique o progresso da criação do índice. A diferença entre FinishTime e CreateTime mostra que a criação do índice invertido para 1 milhão de linhas na coluna timestamp levou apenas 1 segundo.

      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. Após a criação do índice invertido, executar a mesma consulta para contar dados onde a coluna timestamp é maior que 2007-08-23 04:17:00 leva 0,01 segundos. Isso representa uma melhoria de 2 segundos em comparação com a velocidade da consulta sem índice invertido.

      SELECT count() FROM hackernews_1m WHERE timestamp > '2007-08-23 04:17:00';
      +---------+
      | count() |
      +---------+
      |  999081 |
      +---------+
      1 row in set (0.01 sec)
  • Compare o desempenho de uma consulta de igualdade em uma coluna numérica.

    1. Sem um índice invertido, uma consulta para contar linhas onde a coluna parent é igual a 11189 leva 0,01s.

      SELECT count() FROM hackernews_1m WHERE parent = 11189;
      +---------+
      | count() |
      +---------+
      |       2 |
      +---------+
      1 row in set (0.01 sec)
    2. Crie um índice invertido na coluna numérica parent sem tokenizador.

      -- 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. Verifique o progresso da criação do índice.

      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. Execute a mesma consulta novamente. O tempo de consulta permanece 0,01s, não mostrando alteração significativa para este conjunto de dados.

      SELECT count() FROM hackernews_1m WHERE parent = 11189;
      +---------+
      | count() |
      +---------+
      |       2 |
      +---------+
      1 row in set (0.01 sec)
  • Compare o desempenho de uma consulta de igualdade em uma coluna string.

    1. Sem um índice invertido, uma consulta para contar linhas onde a coluna author é igual a 'faster' leva 0,03s.

      SELECT count() FROM hackernews_1m WHERE author = 'faster';
      +---------+
      | count() |
      +---------+
      |      20 |
      +---------+
      1 row in set (0.03 sec)
    2. Crie um índice invertido na coluna author sem tokenizador.

      -- 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. Verifique o progresso da criação do índice.

      -- 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. Após criar o índice, a consulta leva apenas 0,01s, tornando-a 3 vezes mais rápida.

      -- 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)

Função Tokenize

A função TOKENIZE divide uma string de texto em uma sequência de termos. A tokenização é um componente central para construir e usar um índice invertido. A qualidade da tokenização impacta diretamente o desempenho do índice.

Para ver como uma string de texto é tokenizada, use a função TOKENIZE para visualizar o resultado. A função TOKENIZE possui dois parâmetros principais: parser e parser_mode. A tabela a seguir descreve esses parâmetros.

Parameter

Description

parser

Especifica o tokenizador a ser usado. Se este parâmetro for omitido, a função não realiza tokenização.

  • english: Tokenizador para inglês. Adequado para campos que contêm texto em inglês. Tokeniza o texto com base em espaços e pontuação e oferece alto desempenho.

  • chinese: Tokenizador para chinês. Adequado para campos que contêm texto em chinês. Apresenta desempenho mais lento que o tokenizador de inglês.

  • unicode: Tokenizador para idiomas mistos. Adequado para textos com idiomas mistos, como chinês e inglês. Tokeniza prefixos e sufixos de e-mail, endereços IP e strings alfanuméricas. Também tokeniza texto chinês caractere por caractere.

parser_mode

Especifica o modo de tokenização, que determina a granularidade da tokenização.

Todos os tokenizadores usam o modo coarse_grained por padrão. Esse modo tende a segmentar o texto em palavras mais longas. Por exemplo, a string '武汉市长江大桥' é segmentada nas duas palavras '武汉市' e '长江大桥'.

Quando parser=chinese é especificado para o tokenizador chinês, o modo fine_grained também é suportado. O modo fine_grained tende a segmentar o texto em palavras mais curtas. Por exemplo, '武汉市长江大桥' é tokenizado em seis palavras: '武汉', '武汉市', '市长', '长江', '长江大桥' e '大桥'.

Exemplos:

-- 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)