Tous les produits
Search
Centre de documentation

ApsaraDB for SelectDB:Index inversé

Dernière mise à jour :Aug 11, 2026

L'index inversé est une technique d'indexation courante en recherche d'information. Il fonctionne en découpant le texte en termes pour construire un index, ce qui permet de retrouver rapidement les documents contenant ces termes.ApsaraDB for SelectDB prend en charge les index inversés. Cette fonctionnalité permet d'effectuer des recherches plein texte sur des types de données textuelles, ainsi que des requêtes d'égalité et de plage sur des types numériques et de date. Vous pouvez ainsi filtrer rapidement de grands volumes de données pour isoler des informations spécifiques. Cette rubrique décrit la fonctionnalité d'index inversé dans ApsaraDB for SelectDB, notamment sa création et son utilisation.

Fonctionnement

Dans Alibaba Cloud SelectDB, l'index inversé considère chaque ligne d'une table comme un document et chaque colonne comme un champ. Ce mécanisme permet de localiser rapidement les lignes contenant un mot-clé spécifique, améliorant ainsi les performances des requêtes utilisant une clause WHERE.

Contrairement à un index classique, l'index inversé est stocké dans un fichier inversé distinct. Ce fichier est mappé logiquement au fichier de segment sans y être intégré. Cette approche évite de réécrire le fichier de segment lors des mises à jour ou des suppressions d'index, réduisant considérablement la charge de traitement.

Cas d'usage

  • Accélération des recherches plein texte sur les types de données chaîne.

  • Optimisation du filtrage avec les opérateurs =, !=, >, >=, <, <= pour les types chaîne, numérique et datetime.

Avantages

  • Prise en charge complète des opérateurs logiques.

    • Support ajouté pour le pushdown d'index avec la logique OR and NOT.

    • Possibilité de combiner librement plusieurs conditions avec AND, OR, and NOT.

  • Gestion flexible et rapide des index.

    • Création d'un index inversé lors de la création d'une table.

    • Ajout d'un index inversé à une table existante.

    • Suppression d'un index inversé d'une table.

Limites

  • Les types de données à virgule flottante FLOAT et DOUBLE ne prennent pas en charge l'index inversé en raison de problèmes de précision. Utilisez plutôt le type de données à virgule fixe DECIMAL, compatible avec l'index inversé.

  • Certains types de données complexes ne sont pas compatibles avec l'index inversé, notamment MAP, STRUCT, JSON, HLL, BITMAP, QUANTILE_STATE et AGG_STATE. Pour utiliser un index inversé avec des données JSON, convertissez la colonne vers le type de données VARIANT.

  • Bien qu'il soit possible de créer un index inversé sur un champ de type numérique, vous ne pouvez pas spécifier de parser tel que english, chinese ou unicode.

  • Le modèle DUPLICATE et le modèle UNIQUE avec Merge on Write activé prennent en charge l'index inversé sur n'importe quelle colonne. En revanche, le modèle AGGREGATE et le modèle UNIQUE avec Merge on Write désactivé ne le prennent en charge que sur une colonne Key. Comme ces modèles doivent lire et fusionner toutes les données, le système ne peut pas utiliser l'index pour le pré-filtrage.

Créer un index

Vous pouvez créer un index inversé lors de la création de la table ou sur une colonne d'une table existante.

Créer un index lors de la création de la table

Il s'agit d'une opération synchrone. La création de l'index se termine lorsque la table est créée avec succès.

Important

Les index inversés présentent les limites suivantes selon les modèles de données :

  • Pour le modèle de clé agrégée, la création d'un index inversé est uniquement possible sur les colonnes clés.

  • Pour le modèle de clé unique, la fonctionnalité Merge on Write doit être activée. Une fois activée, vous pouvez créer un index inversé sur n'importe quelle colonne.

  • Pour le modèle de clé dupliquée, la création d'un index inversé est autorisée sur n'importe quelle colonne.

Syntaxe

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

Paramètres

Paramètres de création de table

Parameter

Required

Description

db_name

No

Nom de la base de données devant contenir la table.

table_name

Yes

Nom de la table à créer.

column_definition_list

Yes

Liste des définitions de colonnes. Pour plus d'informations, consultez CREATE-TABLE.

table_properties

Yes

Propriétés de la table, telles que le modèle de données, le partitionnement et le bucketing. Pour plus d'informations, consultez modèle de données.

index_definition_list

No

Liste des définitions d'index.

index_definition_list

Lors de la création d'une table, définissez un ou plusieurs index en respectant le format suivant : index_definition[, index_definition][, index_definition]....

index_definition

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

Paramètres

Paramètres obligatoires

Parameter

Description

index_name

Nom de l'index.

column_name

Nom de la colonne à indexer.

index_type

Type d'index. Définissez cette valeur sur USING INVERTED.

Paramètres facultatifs

Properties

La clause PROPERTIES spécifie les options de tokenisation pour l'index. Elle se compose d'une ou plusieurs paires clé-valeur séparées par des virgules, au format "<key>" = "<value>". Si vous n'êtes pas certain de la manière dont un texte sera tokenisé, utilisez la fonction TOKENIZE pour visualiser le résultat. Pour plus d'informations, consultez Fonctions de tokenisation.

Key

Value

parser

Spécifie le tokenizer. Si cette propriété est omise, aucune tokenisation n'est effectuée. La propriété parser n'est pas prise en charge pour les types de données numériques.

  • english : Tokenizer anglais. Idéal pour les textes en anglais, ce tokenizer haute performance sépare les mots en fonction des espaces et de la ponctuation.

  • chinese : Tokenizer chinois. Adapté aux textes contenant des caractères chinois. Ses performances sont inférieures à celles du tokenizer anglais.

  • unicode : Tokenizer Unicode. Conçu pour les textes multilingues, tels que le chinois et l'anglais. Il permet de tokeniser les préfixes et suffixes d'e-mails, les adresses IP et les chaînes alphanumériques. Il tokenise également le texte chinois caractère par caractère.

parser_mode

Spécifie le mode de tokenisation des mots, déterminant ainsi la granularité de la tokenisation.

Tous les tokenizers utilisent le mode coarse_grained par défaut. Ce mode tend à segmenter le texte en mots plus longs. Par exemple, 'Wuhan City Yangtze River Bridge' est segmenté en deux mots : 'Wuhan City' et 'Yangtze River Bridge'.

Lorsque parser=chinese est spécifié pour le tokenizer chinois, le mode fine_grained est également pris en charge. Ce mode tend à tokeniser le texte en mots plus courts. Par exemple, 'Wuhan City Yangtze River Bridge' est tokenisé en six termes : 'Wuhan', 'Wuhan City', 'mayor', 'Yangtze River', 'Yangtze River Bridge' et 'Bridge'.

Pour en savoir plus sur le fonctionnement de la tokenisation, consultez Fonctions de tokenisation.

support_phrase

Indique si l'index prend en charge l'accélération des requêtes de phrase MATCH_PHRASE. La valeur par défaut est false.

  • true : Active la prise en charge, ce qui nécessite davantage d'espace de stockage.

  • false : Désactive la prise en charge pour économiser de l'espace de stockage. Vous pouvez utiliser MATCH_ALL pour rechercher plusieurs termes.

char_filter

Prétraite les chaînes avant la tokenisation. Actuellement, char_filter_type prend uniquement en charge char_replace.

char_replace remplace chaque caractère de char_filter_pattern par le caractère correspondant dans char_filter_replacement.

  • char_filter_pattern : Tableau de caractères à remplacer.

  • Cette propriété est facultative et prend par défaut un caractère espace unique si elle est omise.

ignore_above

Définit une limite de longueur pour les valeurs de chaîne non tokenisées (lorsqu'aucun parser n'est spécifié).

  • Le système n'indexe pas les chaînes dont la longueur dépasse la valeur ignore_above. Pour les tableaux de chaînes, cette limite s'applique à chaque élément.

  • Valeur par défaut : 256 (octets).

lower_case

Indique s'il faut convertir les termes tokenisés en minuscules pour une correspondance insensible à la casse.

  • true : Convertit en minuscules.

  • false : Conserve la casse d'origine.

stopwords

Spécifie une liste de mots vides (stopwords), ce qui influence le comportement du tokenizer.

  • La liste intégrée comprend des mots courants à faible valeur sémantique (tels que is, the et a) que le système ignore lors de l'indexation et des requêtes.

  • none : Utilise une liste vide de mots vides.

dict_compression

Indique s'il faut activer la compression de dictionnaire Zstandard (ZSTD) pour le dictionnaire de l'index inversé.

  • true : Active la compression du dictionnaire.

  • false : (Par défaut) Désactive la compression du dictionnaire.

  • Recommandation : Activez cette option pour les charges de travail impliquant de gros volumes de texte ou de journaux, ou pour réduire les coûts de stockage. Elle fonctionne mieux avec inverted_index_storage_format = "V3" et peut réduire le stockage d'environ 20 % pour les données textuelles et les journaux à grande échelle.

Remarque

Ce paramètre est pris en charge uniquement dans les versions 4.1.0 et ultérieures.

Comment

Parameter

Description

comment

Description de l'index.

Exemple : Créer une table avec un 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;

Ajouter un index

Cette opération est asynchrone. Vérifiez la progression de la création de l'index en exécutant SHOW ALTER TABLE COLUMN;.

Syntaxe

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

Paramètres

Les paramètres sont identiques à ceux utilisés pour la création d'une table.

Exemples

Ajoutez un index sans tokenisation.

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

Ajoutez un index utilisant english pour la tokenisation.

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

Consulter les index inversés

Suivre la progression des modifications d'index

La modification d'un index inversé via les commandes ALTER et DROP est un processus asynchrone. Exécutez l'instruction suivante pour suivre sa progression.

SHOW ALTER TABLE COLUMN;

Lister tous les index inversés d'une table

Syntaxe

SHOW INDEXES FROM <table_name>;

Exemple

SHOW INDEXES FROM user_tb;

Supprimer un index

La suppression d'un index est un processus asynchrone. Pour vérifier la progression, consultez Interroger les informations sur les index inversés.

Important

La suppression d'un index peut dégrader les performances des requêtes. Procédez avec prudence.

Syntaxe

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

Exemple

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

Utilisation de l'index inversé

Recherche plein texte

Syntaxe

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

Paramètres

Parameter

Required

Description

table_name

Yes

Nom de la table.

column_name

Yes

Nom de la colonne.

conditional_logic

Yes

Combinaison d'opérateurs de recherche et d'opérateurs logiques.

Opérateurs logiques : AND, OR, and NOT.

Opérateurs de recherche :

  • MATCH_ALL : Retourne les lignes contenant tous les mots-clés spécifiés.

  • MATCH_ANY : Retourne les lignes contenant au moins l'un des mots-clés spécifiés.

  • MATCH_PHRASE : Retourne les lignes contenant l'expression exacte.

keywords

Yes

Mots-clés de recherche.

Séparez les mots-clés multiples par des espaces.

Exemple : keyword1 keyword2 keyword3.

Exemples

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

Requêtes d'égalité et de plage pour les types numérique et date

La syntaxe de requête suit le standard SQL.

Exemple

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

Comparaison des performances de requête

Cette rubrique utilise un jeu de données hackernews d'un million de lignes pour comparer les performances des requêtes avec et sans index inversé.

Prérequis

Étape 1 : Créez une table.

  1. Créez une base de données.

    CREATE DATABASE test_inverted_index;
  2. Basculez vers la base de données créée.

    USE test_inverted_index;
  3. Créez la table cible.

    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.

Étape 2 : Importez les données

  1. Téléchargez le fichier de données.

    wget https://qa-build.oss-cn-beijing.aliyuncs.com/regression/index/hacknernews_1m.csv.gz
  2. Importez les données à l'aide de Stream Load.

    Sur la page des détails de l'instance ApsaraDB for SelectDB, consultez l'hôte endpoint et le numéro de port d'une instance ApsaraDB for SelectDB. Pour plus d'informations sur Stream Load, consultez 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. Exécutez une requête count() pour vérifier l'importation des données.

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

Comparaison des performances

Remarque
  • Les résultats de comptage peuvent différer entre les requêtes utilisant un index inversé avec tokenizer et celles sans tokenizer. En effet, l'index inversé tokenise les données de la colonne et normalise les termes (par exemple, en les convertissant en minuscules), ce qui peut amener les requêtes utilisant l'index à correspondre à un plus grand nombre de lignes.

  • La différence de performance dans certains exemples peut ne pas être significative car le jeu de données est petit. Plus le volume de données est important, plus l'amélioration des performances est marquée.

Recherche plein texte

  • Comptez les lignes où la colonne comment contient OLAP.

    • Le comptage du nombre de lignes dans la colonne comment contenant OLAP à l'aide de l'opérateur LIKE prend 0,18 s.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%';
      +---------+
      | count() |
      +---------+
      |      34 |
      +---------+
      1 row in set (0.18 sec)
    • La recherche plein texte MATCH_ANY basée sur un index inversé compte le nombre de lignes dans la colonne comment contenant OLAP en 0,02 s. C'est 9 fois plus rapide qu'avec l'opérateur LIKE.

      SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLAP';
      +---------+
      | count() |
      +---------+
      |      35 |
      +---------+
      1 row in set (0.02 sec)
  • Comptez les lignes où la colonne comment contient OLTP.

    • Cette opération compte le nombre de lignes dans la colonne comment contenant OLTP à l'aide de l'opérateur LIKE et prend 0,07 s.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      48 |
      +---------+
      1 row in set (0.07 sec)
    • La recherche plein texte MATCH_ANY basée sur un index inversé compte le nombre de lignes dans la colonne comment contenant OLTP en 0,01 s. C'est 7 fois plus rapide qu'avec l'opérateur LIKE.

      SELECT count() FROM hackernews_1m WHERE comment MATCH_ANY 'OLTP';
      +---------+
      | count() |
      +---------+
      |      51 |
      +---------+
      1 row in set (0.01 sec)
  • Comptez les lignes où la colonne comment contient à la fois OLAP et OLTP.

    • Avec LIKE, la requête prend 0,13 s.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' AND comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      14 |
      +---------+
      1 row in set (0.13 sec)
    • Avec la recherche plein texte utilisant MATCH_ALL, la requête prend 0,01 s, soit 13 fois plus rapide qu'avec LIKE.

       SELECT count() FROM hackernews_1m WHERE comment MATCH_ALL 'OLAP OLTP';
      +---------+
      | count() |
      +---------+
      |      15 |
      +---------+
      1 row in set (0.01 sec)
  • Comptez les lignes où la colonne comment contient soit OLAP soit OLTP.

    • Avec LIKE, la requête prend 0,12 s.

      SELECT count() FROM hackernews_1m WHERE comment LIKE '%OLAP%' OR comment LIKE '%OLTP%';
      +---------+
      | count() |
      +---------+
      |      68 |
      +---------+
      1 row in set (0.12 sec)
    • Avec la recherche plein texte utilisant MATCH_ANY, la requête prend 0,01 s, soit 12 fois plus rapide qu'avec LIKE.

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

Requêtes d'égalité et de plage

  • Comparez les performances d'une requête de plage sur une colonne DateTimeV2.

    1. Sans index inversé, une requête comptant les lignes où timestamp est supérieur à 2007-08-23 04:17:00 prend 0,03 s.

       SELECT count() FROM hackernews_1m WHERE timestamp > '2007-08-23 04:17:00';
      +---------+
      | count() |
      +---------+
      |  999081 |
      +---------+
      1 row in set (0.03 sec)
    2. Ajoutez un index inversé à la colonne timestamp.

      CREATE INDEX idx_timestamp ON hackernews_1m(timestamp) USING INVERTED;
      Query OK, 0 rows affected (0.03 sec)
    3. Vérifiez la progression de la création de l'index. La différence entre FinishTime et CreateTime montre que la création de l'index inversé pour 1 million de lignes sur la colonne timestamp n'a pris qu'une seconde.

      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. Une fois l'index inversé créé, l'exécution de la même requête pour compter les données où la colonne timestamp est supérieure à 2007-08-23 04:17:00 prend 0,01 seconde. Cela représente une amélioration de 2 secondes par rapport à la vitesse de requête sans index inversé.

      SELECT count() FROM hackernews_1m WHERE timestamp > '2007-08-23 04:17:00';
      +---------+
      | count() |
      +---------+
      |  999081 |
      +---------+
      1 row in set (0.01 sec)
  • Comparez les performances d'une requête d'égalité sur une colonne numérique.

    1. Sans index inversé, une requête comptant les lignes où la colonne parent égale 11189 prend 0,01 s.

      SELECT count() FROM hackernews_1m WHERE parent = 11189;
      +---------+
      | count() |
      +---------+
      |       2 |
      +---------+
      1 row in set (0.01 sec)
    2. Créez un index inversé sur la colonne numérique parent sans 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. Vérifiez la progression de la création de l'index.

      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. Exécutez à nouveau la même requête. Le temps de requête reste de 0,01 s, ce qui ne montre aucun changement significatif pour ce jeu de données.

      SELECT count() FROM hackernews_1m WHERE parent = 11189;
      +---------+
      | count() |
      +---------+
      |       2 |
      +---------+
      1 row in set (0.01 sec)
  • Comparez les performances d'une requête d'égalité sur une colonne chaîne.

    1. Sans index inversé, une requête comptant les lignes où la colonne author égale 'faster' prend 0,03 s.

      SELECT count() FROM hackernews_1m WHERE author = 'faster';
      +---------+
      | count() |
      +---------+
      |      20 |
      +---------+
      1 row in set (0.03 sec)
    2. Créez un index inversé sur la colonne author sans 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. Vérifiez la progression de la création de l'index.

      -- 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. Après la création de l'index, la requête ne prend plus que 0,01 s, soit 3 fois plus rapide.

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

Fonction TOKENIZE

La fonction TOKENIZE découpe une chaîne de texte en une séquence de termes. La tokenisation est un composant essentiel pour la construction et l'utilisation d'un index inversé. La qualité de la tokenisation impacte directement les performances de l'index.

Pour observer comment une chaîne de texte est tokenisée, utilisez la fonction TOKENIZE afin de visualiser le résultat. La fonction TOKENIZE possède deux paramètres principaux : parser et parser_mode. Le tableau suivant décrit ces paramètres.

Parameter

Description

parser

Spécifie le tokenizer à utiliser. Si ce paramètre est omis, la fonction n'effectue aucune tokenisation.

  • english : Tokenizer anglais. Adapté aux champs contenant du texte en anglais. Il tokenise le texte en fonction des espaces et de la ponctuation et offre des performances élevées.

  • chinese : Tokenizer chinois. Adapté aux champs contenant du texte en chinois. Il est plus lent que le tokenizer anglais.

  • unicode : Tokenizer multilingue. Adapté aux textes mixtes, tels que le chinois et l'anglais. Il tokenise les préfixes et suffixes d'e-mails, les adresses IP et les chaînes alphanumériques. Il tokenise également le texte chinois caractère par caractère.

parser_mode

Spécifie le mode de tokenisation, déterminant ainsi la granularité de la tokenisation.

Tous les tokenizers utilisent le mode coarse_grained par défaut. Ce mode tend à segmenter le texte en mots plus longs. Par exemple, la chaîne '武汉市长江大桥' est segmentée en deux mots : '武汉市' et '长江大桥'.

Lorsque parser=chinese est spécifié pour le tokenizer chinois, le mode fine_grained est également pris en charge. Le mode fine_grained tend à segmenter le texte en mots plus courts. Par exemple, '武汉市长江大桥' est tokenisé en six mots : '武汉', '武汉市', '市长', '长江', '长江大桥' et '大桥'.

Exemples :

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