La paginación con OFFSET/LIMIT escanea y descarta todas las filas anteriores a la página solicitada, por lo que el tiempo de consulta aumenta de forma lineal según la profundidad de la página. La paginación por cursor evita este problema al registrar la posición de la última fila devuelta e iniciar la siguiente consulta directamente desde esa posición. Utilice la paginación por cursor cuando la paginación convencional con OFFSET/LIMIT resulte demasiado lenta para el tamaño de su conjunto de datos.
Requisitos previos
Antes de empezar, asegúrese de contar con lo siguiente:
LindormTable versión 2.7.8 o posterior. Para comprobar la versión y actualizar, consulte Release notes of LindormTable y Upgrade the minor engine version
Limitaciones
La paginación por cursor solo admite consultas simples. No se admiten consultas con funciones de agregación (
SUM,COUNT), cláusulasORDER BYni cláusulasGROUP BY.La paginación por cursor requiere las cláusulas
OFFSETyLIMIT.
Paginar los resultados
El ciclo de paginación sigue los mismos cuatro pasos para cada consulta:
Ejecute la consulta de la primera página con
_l_next_cursor_en la listaSELECT(o utilice el hint/*+ _l_allow_cursor_ */para consultas con comodines).Del conjunto de resultados, tome el último valor de
_l_next_cursor_; este es el cursor para la siguiente página.Pase ese cursor en la cláusula
WHEREcomo_l_current_cursor_ = '<cursor value>'en las consultas subsecuentes.Deténgase cuando
_l_next_cursor_devuelvanull, ya que habrá llegado a la última página.
Elija el estilo de proyección que se ajuste a su consulta:
|
Estilo |
Cuándo utilizarlo |
|
Proyección explícita (recomendado) |
Cuando sabe qué columnas debe devolver |
|
Proyección implícita |
Cuando necesita todas las columnas, incluidas las dinámicas ( |
Proyección explícita (recomendado)
Incluya _l_next_cursor_ directamente en la lista de columnas.
Primera página:
SELECT <column_identifier1>, <column_identifier2>, _l_next_cursor_ FROM <table_identifier> LIMIT 0, 5;
El resultado incluye una columna _l_next_cursor_ que contiene un valor de cursor VARCHAR para cada fila.
Cada fila del resultado tiene un valor de _l_next_cursor_. Utilice el valor de la última fila como cursor para la siguiente página.
Páginas subsecuentes:
SELECT <column_identifier1>, <column_identifier2>, _l_next_cursor_ FROM <table_identifier> WHERE _l_current_cursor_ = '<cursor value>' AND <filter condition> LIMIT 5, 5;
En la cláusula WHERE, combine la condición del cursor y cualquier condición de filtro original con AND.
Proyección implícita
Cuando la lista de columnas es *, LindormTable devuelve solo las columnas predefinidas y excluye el cursor. Para incluir el cursor en una consulta con comodines, agregue el hint /*+ _l_allow_cursor_ */ después de SELECT.
Primera página:
SELECT /*+ _l_allow_cursor_ */ * FROM <table_identifier> LIMIT 0, 5;
Páginas subsecuentes:
SELECT /*+ _l_allow_cursor_ */ * FROM <table_identifier> WHERE _l_current_cursor_ = '<cursor value>' AND <original filter condition> LIMIT 5, 5;
Utilice la proyección implícita cuando no pueda determinar las columnas con antelación, como al consultar columnas dinámicas.
Ejemplos
A continuación, se utiliza una tabla de ejemplo con 15 filas para demostrar la obtención de tres páginas de cinco filas cada una.
Configure la tabla de ejemplo:
-- Create a sample table.
CREATE TABLE tb_cursor_test(c1 INT , c2 INT, c3 VARCHAR(50), PRIMARY KEY(c1));
-- Insert data into the table.
UPSERT INTO tb_cursor_test(c1, c3) VALUES (1, 'c3_1'),(2, 'c3_2'),(3, 'c3_3'),(4, 'c3_4'),(5, 'c3_5');
UPSERT INTO tb_cursor_test(c1, c3) VALUES (6, 'c3_6'),(7, 'c3_7'),(8, 'c3_8'),(9, 'c3_9'),(10, 'c3_10');
UPSERT INTO tb_cursor_test(c1, c3) VALUES (11, 'c3_11'),(12, 'c3_12'),(13, 'c3_13'),(14, 'c3_14'),(15, 'c3_15');
Paso 1: Obtener la página 1
La consulta de la primera página debe incluir _l_next_cursor_ en la lista SELECT para inicializar la paginación por cursor.
SELECT c1, c2, c3, _l_next_cursor_ FROM tb_cursor_test LIMIT 0, 5;
Salida:
+----+------+------+------------------------------+
| c1 | c2 | c3 | _l_next_cursor_ |
+----+------+------+------------------------------+
| 1 | null | c3_1 | AAAABIAAAAYFAAAABk5PUk1BTA== |
| 2 | null | c3_2 | AAAABIAAAAYFAAAABk5PUk1BTA== |
| 3 | null | c3_3 | AAAABIAAAAYFAAAABk5PUk1BTA== |
| 4 | null | c3_4 | AAAABIAAAAYFAAAABk5PUk1BTA== |
| 5 | null | c3_5 | AAAABIAAAAYFAAAABk5PUk1BTA== |
+----+------+------+------------------------------+
El valor de _l_next_cursor_ de la última fila es AAAABIAAAAYFAAAABk5PUk1BTA==. Utilice este valor para obtener la página 2.
Paso 2: Obtener la página 2
SELECT c1, c2, c3, _l_next_cursor_ FROM tb_cursor_test WHERE _l_current_cursor_ = 'AAAABIAAAAYFAAAABk5PUk1BTA==' LIMIT 5, 5;
Salida:
+----+------+-------+------------------------------+
| c1 | c2 | c3 | _l_next_cursor_ |
+----+------+-------+------------------------------+
| 6 | null | c3_6 | AAAABIAAAAsKAAAABk5PUk1BTA== |
| 7 | null | c3_7 | AAAABIAAAAsKAAAABk5PUk1BTA== |
| 8 | null | c3_8 | AAAABIAAAAsKAAAABk5PUk1BTA== |
| 9 | null | c3_9 | AAAABIAAAAsKAAAABk5PUk1BTA== |
| 10 | null | c3_10 | AAAABIAAAAsKAAAABk5PUk1BTA== |
+----+------+-------+------------------------------+
El siguiente cursor es AAAABIAAAAsKAAAABk5PUk1BTA==. Utilícelo para obtener la página 3.
Paso 3: Obtener la página 3
SELECT c1, c2, c3, _l_next_cursor_ FROM tb_cursor_test WHERE _l_current_cursor_ = 'AAAABIAAAAsKAAAABk5PUk1BTA==' LIMIT 10, 5;
Salida:
+----+------+-------+-----------------+
| c1 | c2 | c3 | _l_next_cursor_ |
+----+------+-------+-----------------+
| 11 | null | c3_11 | null |
| 12 | null | c3_12 | null |
| 13 | null | c3_13 | null |
| 14 | null | c3_14 | null |
| 15 | null | c3_15 | null |
+----+------+-------+-----------------+
El valor de _l_next_cursor_ es null, lo que indica que esta es la última página. Detenga la paginación en este punto.