LindormTable prend en charge les indexes secondaires dans le modèle tabulaire. Les indexes secondaires vous permettent d'interroger des données sur des colonnes ne faisant pas partie de la clé primaire sans modifier la logique d'écriture de votre application : Lindorm gère automatiquement la maintenance des indexes 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 Utilisation du moteur LindormTable avec Lindorm Wide-Table SQL ou Connexion et utilisation de LindormTable avec Lindorm-cli
Concepts clés
Relation entre les indexes 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 indexes pour une seule table principale, y compris des indexes 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 de 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. Vous pouvez ajouter, supprimer ou mettre à jour des indexes à 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 snapshot 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'attente client ou d'erreur d'E/S. Si une écriture échoue en raison d'un délai d'attente 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 elles reste garantie.
Mutabilité
Chaque é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 les opérations effectuées par votre charge de travail, afin de minimiser la surcharge liée à la maintenance des indexes. Définissez cette propriété à l'aide de Table_Options lors de la création ou de la modification d'une table. Consultez la syntaxe CREATE TABLE.
Choisissez un paramètre de mutabilité en fonction de 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 |
Écritures directes dans la table principale |
|
Insertion uniquement, jamais de mise à jour ni de suppression |
|
2 |
Coût le plus faible. Non recommandé : aucune protection n'empêche les mises à jour ; si des mises à jour se produisent, l'index devient silencieusement incohérent avec la table principale |
|
Insertion et suppression par ligne, jamais de mise à jour |
|
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é |
|
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 |
|
4 |
Version optimisée de |
|
Mise à jour et suppression, horodatage personnalisé, sans restriction de version |
|
4 |
Aucune restriction ; utilisez plutôt |
MUTABLE_LATEST est le paramètre 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 cela avant de créer des indexes, 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 requêtes adressées à l'index échoueront immédiatement après sa création. Pour les étapes de récupération, consultez la FAQ.
IMMUTABLEetIMMUTABLE_ROWSne font l'objet d'aucune application côté serveur. Si votre charge de travail met à jour des données mais que la table est définie surIMMUTABLEouIMMUTABLE_ROWS, le serveur ne renvoie pas d'erreur, mais les données de l'index deviennent incohérentes avec 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 actifs-actifs 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 par 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 indexes secondaires dans Lindorm prennent également en charge la mise à jour des données d'index lorsque des horodatages personnalisés sont utilisés, une capacité rare dans les systèmes NoSQL.
Deux cas d'utilisation où cela importe :
Importation simultanée 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 ont la priorité ; les importations historiques ne remplissent que les données non encore mises à jour.
Rattrapage de messages : lorsqu'un système ignore les messages accumulés et traite d'abord les messages actuels, chaque message porte son propre horodatage. Le rattrapage des messages antérieurs applique ultérieurement l'ordre d'écrasement 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 indexes 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 CREATE INDEX pour les détails de la syntaxe.
Lors de l'ajout d'un index à une table contenant des données existantes, 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 séparation des données chaudes et froides est activée, surveillez la limitation du débit de lecture du stockage de capacité pendant la construction de l'index. La limitation du débit de lecture 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 indexes secondaires
Utilisez SHOW INDEX pour afficher les indexes d'une table, y compris leurs noms et leur état actuel.
SHOW INDEX FROM orders;
Modification de l'état de l'index
Utilisez 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 BUILD INDEX.
Suppression d'un index secondaire
Utilisez 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. Si des requêtes actives utilisent l'index, supprimez-le avec prudence.
Optimisation des requêtes
Lindorm sélectionne les indexes à 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 montrent comment l'optimiseur sélectionne les indexes pour une table comportant plusieurs indexes :
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 |
|
|
|
Correspondance exacte du préfixe sur |
|
|
|
Correspond avec le préfixe |
|
|
|
Correspond avec le préfixe |
|
|
|
|
Une requête ne peut utiliser qu'un seul index à la fois ; la fusion d'indexes n'est pas prise en charge.
Pour influencer la sélection de l'index, utilisez des indices de requête. Consultez 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 indexes sont pris en charge uniquement sur les tables à version unique. Les tables multiversions ne prennent pas en charge les indexes.
Le TTL au niveau des cellules n'est pas pris en charge. Les tables d'index héritent du TTL de la table principale ; vous ne pouvez pas définir un TTL séparé pour une table d'index.
Pour LindormTable 2.8.6 et versions ultérieures : jusqu'à 10 indexes par table principale, jusqu'à 8 colonnes d'index par index. Pour les versions antérieures : jusqu'à 5 indexes 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 index. Les requêtes avec fusion d'indexes ne sont pas prises en charge.
Les indexes secondaires ne prennent pas en charge la fonctionnalité d'augmentation par lots.
L'ordre de tri des résultats d'une requête d'index secondaire diffère de celui de la table principale.
Les indexes ne peuvent pas être construits pour les données importées via Bulkload. Les indexes 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
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é. 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é en
MUTABLE_UDT.Créez à nouveau l'index.
Si des requêtes actives interrogent l'index, sa suppression affectera ces requêtes. Planifiez en conséquence avant de procéder.
Pour d'autres problèmes liés aux indexes, rejoignez le groupe DingTalk Lindorm ou soumettez un ticket. Consultez le support technique.