LindormTable prend en charge les index secondaires dans le modèle Tabular. Les index secondaires vous permettent d'interroger des données sur des colonnes hors clé primaire sans modifier la logique d'écriture de votre application : Lindorm gère automatiquement la maintenance des index et garantit la cohérence entre la table principale et toutes les tables d'index.
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Une instance Lindorm
Un client SQL connecté à LindormTable. Consultez les rubriques Utilisation du moteur LindormTable avec Lindorm Wide-Table SQL ou Connexion et utilisation de LindormTable avec Lindorm-cli
Concepts clés
Relation entre les index et les tables principales
Chaque index secondaire correspond à une table de données physique indépendante, distincte de la table principale. Vous pouvez créer plusieurs index pour une seule table principale, y compris des index composites basés sur une ou plusieurs colonnes. Lorsque vous écrivez dans la table principale, Lindorm met automatiquement à jour toutes les tables d'index associées. Lors de l'interrogation, spécifiez les conditions dans la clause WHERE relative à la table principale ; Lindorm sélectionne automatiquement le meilleur index, avec un repli sur la table principale si aucun index ne convient.
Modification de schéma en ligne
Les modifications d'index (ajout, désactivation ou suppression) n'affectent pas les opérations de lecture ou d'écriture normales sur la table principale. Ajoutez, supprimez ou mettez à jour des index à tout moment, sans interruption de service.
Cohérence forte
La cohérence des données entre la table principale et les tables d'index est soumise aux contraintes suivantes :
L'isolation par instantané n'est pas prise en charge. Les données écrites dans la table principale peuvent ne pas être immédiatement visibles dans les tables d'index. Une fois que le serveur renvoie une réponse de succès, les données deviennent visibles dans les deux.
Comportement en cas de délai d'expiration du client ou d'erreur d'E/S. Si une écriture échoue en raison d'un délai d'expiration du client ou d'une erreur d'E/S, les données peuvent ne pas apparaître dans la table principale ni dans les tables d'index. La cohérence à terme entre ces dernières reste garantie.
Mutabilité
Toute écriture dans une table indexée coûte plus cher qu'une écriture dans une table simple, car l'index doit être maintenu. Le coût réel dépend du fait que votre charge de travail mette à jour ou supprime des lignes existantes.
La propriété MUTABILITY indique à Lindorm quelles opérations votre charge de travail effectue, afin de minimiser la surcharge liée à la maintenance des index. Définissez cette propriété à l'aide de Table_Options lors de la création ou de la modification d'une table. Consultez la rubrique Syntaxe CREATE TABLE.
Choisissez un paramètre de mutabilité adapté à votre modèle d'écriture :
Ajout uniquement, sans mise à jour ni suppression : utilisez
IMMUTABLEAjout et suppressions au niveau des lignes, sans mise à jour : utilisez
IMMUTABLE_ROWSMises à jour et suppressions, sans horodatage personnalisé : utilisez
MUTABLE_LATEST(recommandé)Mises à jour et suppressions avec horodatage personnalisé : utilisez
MUTABLE_UDT
| Modèle de charge de travail | Paramètre | Coût de l'opération | Notes |
|---|---|---|---|
| Aucun index | — | 1 | Écriture directe dans la table principale |
| Insertion uniquement, jamais de mise à jour ni de suppression | IMMUTABLE |
2 | Coût le plus faible. Non recommandé : aucune protection n'empêche les mises à jour ; si des mises à jour surviennent, l'index devient silencieusement incohérent avec la table principale |
| Insertion et suppression par ligne, jamais de mise à jour | IMMUTABLE_ROWS |
2–3 | Deuxième coût le plus faible. Non recommandé : même mise en garde, les mises à jour provoquent une incohérence silencieuse |
| Mise à jour et suppression, sans horodatage personnalisé | MUTABLE_LATEST(recommandé) |
4 | Valeur par défaut pour LindormTable 2.7.9 et versions ultérieures. Meilleur équilibre entre sécurité et performances |
| Mise à jour et suppression, horodatage personnalisé requis | MUTABLE_UDT |
4 | Version optimisée de MUTABLE_ALL. Nécessite LindormTable 2.6.7 ou version ultérieure |
| Mise à jour et suppression, horodatage personnalisé, sans restrictions de version | MUTABLE_ALL |
4 | Aucune restriction ; utilisez plutôt MUTABLE_UDT pour de meilleures performances |
Le paramètre MUTABLE_LATEST est recommandé. Pour LindormTable 2.7.9 et versions ultérieures, il s'agit de la valeur par défaut. Si votre instance exécute une version antérieure, définissez explicitement MUTABILITY='MUTABLE_LATEST'.
Pour écrire des données avec un horodatage personnalisé, utilisez MUTABLE_UDT (nécessite LindormTable 2.6.7 ou version ultérieure). Planifiez cette configuration avant de créer les index, car la propriété de mutabilité prend effet au moment de la création de l'index.
Si vous écrivez des données avec un horodatage personnalisé sans avoir défini la mutabilité sur MUTABLE_UDT ou MUTABLE_ALL avant la création de l'index, les interrogations via l'index échoueront immédiatement après sa création. Pour les étapes de récupération, consultez la section FAQ.
Les paramètresIMMUTABLEetIMMUTABLE_ROWSne font l'objet d'aucune application côté serveur. Si votre charge de travail met à jour des données alors que la table est configurée surIMMUTABLEouIMMUTABLE_ROWS, le serveur ne renvoie pas d'erreur, mais les données de l'index deviennent incohérentes avec celles de la table principale. N'utilisez ces paramètres que si vous êtes certain qu'aucune mise à jour ne se produira. Étant donné que les tablesIMMUTABLEn'impliquent aucune suppression, elles prennent entièrement en charge les déploiements actif-actif multi-centres de données Internet (IDC).
Index couvrants
Sans index couvrant, une requête qui correspond à une entrée d'index doit toujours récupérer la ligne complète depuis la table principale. Les rowkeys renvoyés par l'index peuvent être dispersés dans la table principale, ce qui nécessite plusieurs appels de procédure distante (RPC) et augmente le temps de réponse (RT) à mesure que l'ensemble de résultats s'agrandit.
Un index couvrant inclut directement les colonnes de la table principale dans la table d'index, éliminant ainsi les recherches dans la table principale pour ces colonnes. Lindorm prend en charge trois modes de couverture :
Specific columns : répertoriez les colonnes à répliquer depuis la table principale.
Toutes les colonnes du schéma (
COVERED_ALL_COLUMNS_IN_SCHEMA) : inclut toutes les colonnes actuellement définies dans le schéma de la table principale. Lorsqu'une nouvelle colonne est ajoutée à la table principale, l'index l'inclut automatiquement, sans nécessiter de réindexation.Colonnes dynamiques (
DYNAMIC) : inclut toutes les colonnes dynamiques de la table principale, ainsi que toutes les colonnes définies dans le schéma.
Horodatages personnalisés (User-Defined Timestamp, UDT)
Lindorm prend en charge les horodatages personnalisés au niveau des colonnes. L'écriture de données avec un horodatage personnalisé est courante dans les systèmes basés sur HBase pour contrôler la durée de vie (TTL) et gérer les écritures hors ordre ou idempotentes. Les index secondaires de Lindorm prennent également en charge la mise à jour des données d'index lors de l'utilisation d'horodatages personnalisés, une fonctionnalité rare dans les systèmes NoSQL.
Deux cas d'utilisation où cela importe :
Importation concurrente et mises à jour en temps réel : utilisez l'heure actuelle pour les écritures en temps réel et un horodatage antérieur (par exemple, 23:59:59 de la veille) pour les importations historiques. Les écritures en temps réel sont prioritaires ; les importations historiques complètent uniquement les données qui n'ont pas encore été mises à jour.
Rattrapage de messages : lorsqu'un système ignore les messages accumulés et traite d'abord les actuels, chaque message porte son propre horodatage. Le rattrapage ultérieur des messages antérieurs applique l'ordre de remplacement correct, indépendamment de la séquence de traitement.
Création d'un index secondaire
Après avoir créé une table principale Lindorm, créez des index secondaires sur ses colonnes à l'aide de l'instruction CREATE INDEX.
L'exemple suivant utilise une table orders . Un index sur la colonne user_id vous permet d'interroger les commandes par utilisateur sans analyser toute la table.
-- Create the primary table
CREATE TABLE orders (
order_id VARCHAR NOT NULL,
user_id VARCHAR,
status VARCHAR,
amount DOUBLE,
created BIGINT,
PRIMARY KEY(order_id)
) WITH (CONSISTENCY = 'strong', MUTABILITY = 'MUTABLE_LATEST');
-- Create a covering index on user_id, including all schema columns
-- Queries filtering on user_id hit this index and avoid primary table lookups
CREATE INDEX idx_user ON orders(user_id) WITH (INDEX_COVERED_TYPE = 'COVERED_ALL_COLUMNS_IN_SCHEMA');
-- This query uses idx_user automatically
SELECT * FROM orders WHERE user_id = 'u123';
Choisissez la création synchrone ou asynchrone de l'index en fonction de la taille de votre table principale. Utilisez la création synchrone pour les petites tables et la création asynchrone pour les grandes. Consultez la rubrique CREATE INDEX pour plus de détails sur la syntaxe.
Lors de l'ajout d'un index à une table contenant déjà des données, l'instruction CREATE INDEX synchronise les données historiques de la table principale vers la table d'index. Cela peut prendre beaucoup de temps pour les grandes tables. La synchronisation s'exécute côté serveur ; l'arrêt du processus Lindorm Shell ne l'interrompt pas.
Si la fonctionnalité de séparation des données chaudes et froides est activée, surveillez la limitation du débit du stockage froid pendant la construction de l'index. La limitation des lectures du stockage froid réduit la vitesse de construction de l'index et peut exercer une contre-pression sur les opérations d'écriture.
Affichage des index secondaires
Utilisez la commande SHOW INDEX pour afficher les index d'une table, y compris leurs noms et leur statut actuel.
SHOW INDEX FROM orders;
Modification du statut de l'index
Utilisez la commande ALTER INDEX pour activer ou désactiver un index secondaire.
-- Activate an index
ALTER INDEX IF EXISTS idx_user ON orders ACTIVE;
-- Disable an index
ALTER INDEX idx_user ON orders DISABLED;
Ne changez pas directement un index DISABLED en ACTIVE , car cela entraînerait une perte de données. Exécutez d'abord une opération BUILD INDEX pour reconstruire les données de l'index, puis activez-le.
Si la table principale contient des données historiques après la création de l'index, exécutez une opération de reconstruction sur l'index avant de l'activer. Consultez la rubrique BUILD INDEX.
Suppression d'un index secondaire
Utilisez la commande DROP INDEX pour supprimer un index secondaire d'une table principale.
DROP INDEX IF EXISTS idx_user ON orders;
La suppression d'un index nécessite l'autorisation Trash. Soyez prudent lors de la suppression si des requêtes actives utilisent l'index.
Optimisation des requêtes
Lindorm sélectionne les index à l'aide de l'optimisation basée sur les règles (RBO). Il fait correspondre le préfixe de chaque index avec la clause WHERE de la requête et sélectionne l'index présentant le degré de correspondance le plus élevé.
Les exemples suivants illustrent la manière dont l'optimiseur sélectionne les index pour une table comportant plusieurs index :
CREATE TABLE dt (rowkey VARCHAR, c1 VARCHAR, c2 VARCHAR, c3 VARCHAR, c4 VARCHAR, c5 VARCHAR, PRIMARY KEY(rowkey));
CREATE INDEX idx1 ON dt(c1);
CREATE INDEX idx2 ON dt(c2, c3, c4);
CREATE INDEX idx3 ON dt(c3) INCLUDE(c1, c2, c4);
CREATE INDEX idx4 ON dt(c5 DESC) WITH (INDEX_COVERED_TYPE = 'COVERED_ALL_COLUMNS_IN_SCHEMA');
| Requête | Index sélectionné | Pourquoi |
|---|---|---|
SELECT rowkey FROM dt WHERE c1 = 'a' |
idx1 |
Correspondance exacte du préfixe sur c1 |
SELECT rowkey FROM dt WHERE c2 = 'b' AND c4 = 'd' |
idx2 |
Correspondance du préfixe c2 ; c3 est absent de la clause WHERE, donc c4 est filtré ligne par ligne après l'analyse de l'index |
SELECT * FROM dt WHERE c2 = 'b' AND c3 >= 'c' AND c3 < 'f' |
idx2 |
Correspondance du préfixe c2, c3 ; SELECT * nécessite une recherche dans la table principale car idx2 n'inclut pas toutes les colonnes. Des rowkeys dispersés peuvent entraîner plusieurs RPC, augmentant le RT pour les grands ensembles de résultats |
SELECT * FROM dt WHERE c5 = 'c' |
idx4 |
idx4 est un index couvrant complet ; SELECT * ne nécessite pas de recherche dans la table principale |
Une requête ne peut utiliser qu'un seul index à la fois ; la fusion d'index n'est pas prise en charge.
Pour influencer la sélection des index, utilisez des indicateurs de requête. Consultez la rubrique CREATE INDEX.
Limites
Les noms d'index doivent être uniques par table principale. Le même nom d'index peut être utilisé sur différentes tables principales.
Les index sont pris en charge uniquement sur les tables à version unique. Les tables multiversions ne prennent pas en charge les index.
La TTL au niveau des cellules n'est pas prise en charge. Les tables d'index héritent de la TTL de la table principale ; vous ne pouvez pas définir une TTL distincte pour une table d'index.
Pour LindormTable 2.8.6 et versions ultérieures : jusqu'à 10 index par table principale, jusqu'à 8 colonnes d'index par index. Pour les versions antérieures : jusqu'à 5 index et jusqu'à 3 colonnes d'index.
La longueur combinée des colonnes d'index et de la clé primaire ne doit pas dépasser 30 Ko. Évitez d'utiliser des colonnes de plus de 100 octets comme colonnes d'index.
Une requête utilise au maximum un seul index. Les requêtes avec fusion d'index ne sont pas prises en charge.
Les index secondaires ne prennent pas en charge la fonctionnalité d'augmentation par lot.
L'ordre de tri des résultats d'une requête via un index secondaire diffère de celui de la table principale.
Les index ne peuvent pas être construits pour les données importées via Bulkload. Les index s'appliquent uniquement aux données écrites via SQL ou une API.
La création d'un index sur une grande table entraîne une exécution prolongée de l'instruction
CREATE INDEXpendant la synchronisation des données historiques.
FAQ
Pourquoi l'erreur User-Defined-Timestamp(UDT) is not supported by table in MUTABLE_LATEST mode apparaît-elle ?
Vous avez créé un index alors que la mutabilité de la table était définie sur MUTABLE_LATEST , mais votre application écrit des données avec un horodatage personnalisé. Le mode MUTABLE_LATEST ne prend pas en charge les horodatages personnalisés.
Pour résoudre ce problème :
Supprimez l'index de la table principale.
Modifiez la propriété de mutabilité pour la définir sur
MUTABLE_UDT.Créez à nouveau l'index.
Si des requêtes actives interrogent l'index, sa suppression affectera ces requêtes. Planifiez vos actions en conséquence avant de procéder.
Pour d'autres problèmes liés aux index, rejoignez le groupe DingTalk Lindorm ou ouvrez un ticket. Consultez la rubrique Support technique.