LindormTable admite índices secundarios en el modelo Tabular. Estos índices le permiten consultar datos en columnas que no forman parte de la clave principal sin modificar la lógica de escritura de su aplicación. Lindorm se encarga automáticamente del mantenimiento de los índices y garantiza la consistencia entre la tabla principal y todas las tablas de índice.
Requisitos previos
Antes de empezar, asegúrese de contar con lo siguiente:
Una instancia de Lindorm.
Un cliente SQL conectado a LindormTable. Consulte Using the LindormTable Engine with Lindorm Wide-Table SQL o Connect to and use LindormTable with Lindorm-cli.
Conceptos clave
Relación entre los índices y las tablas principales
Cada índice secundario se asigna a una tabla de datos física independiente, separada de la tabla principal. Es posible crear varios índices para una sola tabla principal, incluidos índices compuestos basados en una o más columnas. Cuando escribe en la tabla principal, Lindorm actualiza automáticamente todas las tablas de índice asociadas. Al consultar, especifique las condiciones en la cláusula WHERE sobre la tabla principal; Lindorm selecciona el mejor índice de forma automática e incluso recurre a la tabla principal si ningún índice resulta adecuado.
Online Schema Change
Las modificaciones de índices (agregar, deshabilitar o eliminar un índice) no afectan las operaciones normales de lectura o escritura en la tabla principal. Puede agregar, eliminar o actualizar índices en cualquier momento sin tiempo de inactividad.
Consistencia fuerte
La consistencia de los datos entre la tabla principal y las tablas de índice tiene las siguientes restricciones:
No se admite el aislamiento de instantáneas. Los datos escritos en la tabla principal podrían no ser visibles de inmediato en las tablas de índice. Una vez que el servidor devuelve una respuesta exitosa, los datos se vuelven visibles en ambas.
Comportamiento ante tiempos de espera del cliente o errores de E/S. Si una escritura falla por un tiempo de espera del cliente o un error de E/S, es posible que los datos no aparezcan ni en la tabla principal ni en las tablas de índice. Aun así, se garantiza la consistencia eventual entre ellas.
Mutabilidad
Cada escritura en una tabla indexada tiene un costo mayor que en una tabla simple, ya que se debe mantener el índice. El costo real depende de si su carga de trabajo actualiza o elimina filas existentes.
La propiedad MUTABILITY le indica a Lindorm qué operaciones ejecuta su carga de trabajo, de modo que pueda minimizar la sobrecarga del mantenimiento de índices. Establezca esta propiedad mediante Table_Options cuando cree o modifique una tabla. Consulte CREATE TABLE syntax.
Elija la configuración de mutabilidad según su patrón de escritura:
Solo anexado, sin actualizaciones ni eliminaciones: use
IMMUTABLE.Anexado y eliminación a nivel de fila, sin actualizaciones: use
IMMUTABLE_ROWS.Actualizaciones y eliminaciones, sin marca de tiempo personalizada: use
MUTABLE_LATEST(recomendado).Actualizaciones y eliminaciones con marca de tiempo personalizada: use
MUTABLE_UDT.
|
Workload pattern |
Setting |
Operation cost |
Notes |
|
Sin índice |
— |
1 |
Escribe directamente en la tabla principal |
|
Solo inserción, sin actualizaciones ni eliminaciones |
|
2 |
Costo más bajo. No recomendado: no existe ninguna protección que evite las actualizaciones; si ocurren, el índice pierde consistencia con la tabla principal de forma silenciosa |
|
Inserción y eliminación por fila, sin actualizaciones |
|
2–3 |
Segundo costo más bajo. No recomendado: misma advertencia, las actualizaciones provocan inconsistencia silenciosa |
|
Actualización y eliminación, sin marca de tiempo personalizada |
|
4 |
Valor predeterminado en LindormTable 2.7.9 y versiones posteriores. Ofrece el mejor equilibrio entre seguridad y rendimiento |
|
Actualización y eliminación, requiere marca de tiempo personalizada |
|
4 |
Versión optimizada de |
|
Actualización y eliminación, marca de tiempo personalizada, sin restricciones de versión |
|
4 |
Sin restricciones; utilice |
Se recomienda usar MUTABLE_LATEST, que además es el valor predeterminado en LindormTable 2.7.9 y versiones posteriores. Si su instancia ejecuta una versión anterior, establezca MUTABILITY='MUTABLE_LATEST' de manera explícita.
Para escribir datos con una marca de tiempo personalizada, use MUTABLE_UDT (requiere LindormTable 2.6.7 o posterior). Planifique esto antes de crear los índices, ya que la propiedad de mutabilidad surte efecto al momento de crearlos.
Si escribe datos con una marca de tiempo personalizada pero no configuró la mutabilidad como MUTABLE_UDT o MUTABLE_ALL antes de crear el índice, las consultas sobre este fallarán inmediatamente después de su creación. Para conocer los pasos de recuperación, consulte FAQ.
IMMUTABLEyIMMUTABLE_ROWSno cuentan con validación del lado del servidor. Si su carga de trabajo actualiza datos pero la tabla está configurada comoIMMUTABLEoIMMUTABLE_ROWS, el servidor no devuelve ningún error, pero los datos del índice pierden consistencia con la tabla principal. Utilice estas configuraciones solo cuando tenga la certeza de que no habrá actualizaciones. Dado que las tablasIMMUTABLEno implican eliminaciones, admiten por completo los despliegues activo-activo en múltiples centros de datos de Internet (IDC).
Índices de cobertura
Sin un índice de cobertura, una consulta que coincide con una entrada de índice aún necesita recuperar la fila completa desde la tabla principal. Las rowkeys que devuelve el índice pueden estar dispersas en la tabla principal, lo que exige varias llamadas a procedimientos remotos (RPC) y aumenta el tiempo de respuesta (RT) conforme crece el conjunto de resultados.
Un índice de cobertura incluye columnas de la tabla principal directamente en la tabla de índice, lo que elimina las búsquedas en la tabla principal para esas columnas. Lindorm admite tres modos de cobertura:
Specific columns: enumere las columnas que desea replicar desde la tabla principal.
Todas las columnas del esquema (
COVERED_ALL_COLUMNS_IN_SCHEMA): incluye todas las columnas definidas actualmente en el esquema de la tabla principal. Cuando se agrega una nueva columna a la tabla principal, el índice la incorpora de forma automática, sin necesidad de reindexar.Columnas dinámicas (
DYNAMIC): incluye todas las columnas dinámicas de la tabla principal, además de todas las columnas definidas en el esquema.
Marcas de tiempo personalizadas (User-Defined Timestamp, UDT)
Lindorm admite marcas de tiempo personalizadas a nivel de columna. Escribir datos con una marca de tiempo personalizada es común en sistemas basados en HBase para controlar el tiempo de vida (TTL) y gestionar escrituras fuera de orden o idempotentes. Los índices secundarios en Lindorm también permiten actualizar los datos del índice cuando se usan marcas de tiempo personalizadas, una capacidad poco habitual en los sistemas NoSQL.
A continuación se presentan dos casos de uso donde esto resulta relevante:
Importación simultánea y actualizaciones en tiempo real: utilice la hora actual para las escrituras en tiempo real y una marca de tiempo anterior (por ejemplo, las 23:59:59 del día anterior) para las importaciones históricas. Las escrituras en tiempo real tienen prioridad, mientras que las importaciones históricas solo completan los datos que aún no se han actualizado.
Puesta al día de mensajes: cuando un sistema omite los mensajes acumulados y procesa primero los actuales, cada mensaje lleva su propia marca de tiempo. Procesar posteriormente los mensajes anteriores aplica el orden de sobrescritura correcto, sin importar la secuencia de procesamiento.
Crear un índice secundario
Después de crear una tabla principal de Lindorm, construya índices secundarios en sus columnas mediante la instrucción CREATE INDEX.
El siguiente ejemplo utiliza una tabla orders. Un índice en la columna user_id le permite consultar pedidos por usuario sin examinar toda la tabla.
-- 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';
Elija la creación de índices síncrona o asíncrona según el tamaño de su tabla principal. Use la creación síncrona para tablas pequeñas y la asíncrona para las grandes. Consulte CREATE INDEX para conocer los detalles de sintaxis.
Al agregar un índice a una tabla que ya contiene datos, CREATE INDEX sincroniza los datos históricos de la tabla principal hacia la tabla de índice. Este proceso puede tardar bastante en tablas grandes. La sincronización se ejecuta del lado del servidor, por lo que finalizar el proceso de Lindorm Shell no la interrumpe.
Si hot and cold data separation está habilitado, supervise Capacity storage read throttling durante la construcción del índice. La limitación de lecturas en el almacenamiento en frío reduce la velocidad de construcción del índice y puede generar contrapresión en las operaciones de escritura.
Consultar índices secundarios
Utilice SHOW INDEX para consultar los índices de una tabla, incluidos sus nombres y estado actual.
SHOW INDEX FROM orders;
Cambiar el estado de un índice
Utilice ALTER INDEX para activar o deshabilitar un índice secundario.
-- Activate an index
ALTER INDEX IF EXISTS idx_user ON orders ACTIVE;
-- Disable an index
ALTER INDEX idx_user ON orders DISABLED;
No cambie un índice DISABLED directamente a ACTIVE, ya que esto provoca pérdida de datos. Ejecute primero una operación BUILD INDEX para reconstruir los datos del índice y luego actívelo.
Si la tabla principal contiene datos históricos tras la creación del índice, ejecute una operación de reconstrucción sobre este antes de activarlo. Consulte BUILD INDEX.
Eliminar un índice secundario
Utilice DROP INDEX para quitar un índice secundario de una tabla principal.
DROP INDEX IF EXISTS idx_user ON orders;
Eliminar un índice requiere el permiso Trash. Si hay consultas activas que utilizan el índice, proceda con precaución al eliminarlo.
Optimización de consultas
Lindorm selecciona los índices mediante Rule Based Optimization (RBO). Compara el prefijo de cada índice con la cláusula WHERE de la consulta y elige aquel con el mayor grado de coincidencia.
Los siguientes ejemplos muestran cómo el optimizador selecciona índices en una tabla con varios de ellos:
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');
|
Query |
Index selected |
Why |
|
|
|
Coincidencia exacta del prefijo en |
|
|
|
Coincide con el prefijo |
|
|
|
Coincide con el prefijo |
|
|
|
|
Una consulta puede usar un máximo de un índice a la vez, ya que no se admite la combinación de índices.
Para influir en la selección del índice, utilice sugerencias de consulta. Consulte CREATE INDEX.
Límites
Los nombres de los índices deben ser únicos dentro de cada tabla principal. Se puede usar el mismo nombre de índice en distintas tablas principales.
Los índices solo son compatibles con tablas de versión única. Las tablas multiversión no los admiten.
No se admite el TTL a nivel de celda. Las tablas de índice heredan el TTL de la tabla principal; no es posible establecer un TTL independiente para una tabla de índice.
En LindormTable 2.8.6 y versiones posteriores: hasta 10 índices por tabla principal y hasta 8 columnas de índice por índice. En versiones anteriores: hasta 5 índices y hasta 3 columnas de índice.
La longitud combinada de las columnas de índice y la clave principal no debe superar los 30 KB. Evite usar columnas mayores a 100 bytes como columnas de índice.
Una consulta utiliza un máximo de un índice. No se admiten consultas con combinación de índices.
Los índices secundarios no admiten la función de incremento por lotes.
El orden de clasificación de los resultados de una consulta con índice secundario difiere del de la tabla principal.
No es posible construir índices para los datos importados mediante Bulkload. Los índices solo aplican a los datos escritos a través de SQL o una API.
Crear un índice en una tabla grande hace que
CREATE INDEXse ejecute durante mucho tiempo mientras se sincronizan los datos históricos.
Preguntas frecuentes
¿Por qué aparece el error User-Defined-Timestamp(UDT) is not supported by table in MUTABLE_LATEST mode?
Creó un índice mientras la mutabilidad de la tabla estaba configurada como MUTABLE_LATEST, pero su aplicación escribe datos con una marca de tiempo personalizada. MUTABLE_LATEST no admite marcas de tiempo personalizadas.
Para solucionarlo:
Elimine el índice de la tabla principal.
Cambie la propiedad de mutabilidad a
MUTABLE_UDT.Vuelva a crear el índice.
Si hay consultas activas que acceden al índice, eliminarlo las afectará. Planifique adecuadamente antes de continuar.
Para otros problemas relacionados con índices, únase al grupo de DingTalk de Lindorm o envíe un ticket. Consulte Technical support.