A paginação com OFFSET/LIMIT varre e descarta todas as linhas anteriores à página solicitada. Isso faz o tempo de consulta crescer linearmente conforme a profundidade da página aumenta. A paginação por cursor evita esse problema ao registrar a posição da última linha retornada e iniciar a próxima consulta diretamente dessa posição. Use a paginação por cursor quando a paginação convencional com OFFSET/LIMIT for muito lenta para o tamanho do seu conjunto de dados.
Pré-requisitos
Antes de começar, verifique se você tem:
LindormTable versão 2.7.8 ou posterior. Para verificar a versão e atualizar, consulte Release notes of LindormTable e Upgrade the minor engine version
Limitações
A paginação por cursor suporta apenas consultas simples. Não há suporte para consultas com funções de agregação (
SUM,COUNT), cláusulasORDER BYou cláusulasGROUP BY.A paginação por cursor exige as cláusulas
OFFSETeLIMIT.
Paginar pelos resultados
O loop de paginação segue os mesmos quatro passos para cada consulta:
Execute a consulta da primeira página incluindo
_l_next_cursor_na listaSELECT(ou use a dica/*+ _l_allow_cursor_ */para consultas com wildcard).Obtenha o último valor de
_l_next_cursor_no conjunto de resultados. Este é o cursor para a próxima página.Passe esse cursor na cláusula
WHEREcomo_l_current_cursor_ = '<cursor value>'nas consultas subsequentes.Interrompa o processo quando
_l_next_cursor_retornarnull. Isso indica que você atingiu a última página.
Escolha o estilo de projeção adequado à sua consulta:
|
Estilo |
Quando usar |
|
Projeção explícita (recomendado) |
Você sabe exatamente quais colunas retornar |
|
Projeção implícita |
Todas as colunas são necessárias, incluindo as dinâmicas ( |
Projeção explícita (recomendado)
Inclua _l_next_cursor_ diretamente na lista de colunas.
Primeira página:
SELECT <column_identifier1>, <column_identifier2>, _l_next_cursor_ FROM <table_identifier> LIMIT 0, 5;
O resultado inclui uma coluna _l_next_cursor_ com um valor de cursor VARCHAR para cada linha.
Cada linha no resultado tem um valor de _l_next_cursor_. Use o valor da última linha como cursor para a próxima página.
Páginas subsequentes:
SELECT <column_identifier1>, <column_identifier2>, _l_next_cursor_ FROM <table_identifier> WHERE _l_current_cursor_ = '<cursor value>' AND <filter condition> LIMIT 5, 5;
Na cláusula WHERE, combine a condição do cursor e qualquer condição de filtro original usando AND.
Projeção implícita
Se a lista de colunas for *, o LindormTable retorna apenas colunas predefinidas e exclui o cursor. Para incluir o cursor em uma consulta com wildcard, adicione a dica /*+ _l_allow_cursor_ */ após SELECT.
Primeira página:
SELECT /*+ _l_allow_cursor_ */ * FROM <table_identifier> LIMIT 0, 5;
Páginas subsequentes:
SELECT /*+ _l_allow_cursor_ */ * FROM <table_identifier> WHERE _l_current_cursor_ = '<cursor value>' AND <original filter condition> LIMIT 5, 5;
Use a projeção implícita quando não for possível determinar as colunas antecipadamente, como em consultas a colunas dinâmicas.
Exemplos
Os exemplos abaixo usam uma tabela de amostra com 15 linhas para demonstrar a busca de três páginas com cinco linhas cada.
Defina a tabela de amostra:
-- 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');
Passo 1: Buscar a página 1
A consulta da primeira página deve incluir _l_next_cursor_ na lista SELECT para inicializar a paginação por cursor.
SELECT c1, c2, c3, _l_next_cursor_ FROM tb_cursor_test LIMIT 0, 5;
Saída:
+----+------+------+------------------------------+
| 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== |
+----+------+------+------------------------------+
O valor de _l_next_cursor_ da última linha é AAAABIAAAAYFAAAABk5PUk1BTA==. Use este valor para buscar a página 2.
Passo 2: Buscar a página 2
SELECT c1, c2, c3, _l_next_cursor_ FROM tb_cursor_test WHERE _l_current_cursor_ = 'AAAABIAAAAYFAAAABk5PUk1BTA==' LIMIT 5, 5;
Saída:
+----+------+-------+------------------------------+
| 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== |
+----+------+-------+------------------------------+
O próximo cursor é AAAABIAAAAsKAAAABk5PUk1BTA==. Use-o para buscar a página 3.
Passo 3: Buscar a página 3
SELECT c1, c2, c3, _l_next_cursor_ FROM tb_cursor_test WHERE _l_current_cursor_ = 'AAAABIAAAAsKAAAABk5PUk1BTA==' LIMIT 10, 5;
Saída:
+----+------+-------+-----------------+
| 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 |
+----+------+-------+-----------------+
Como _l_next_cursor_ é null, esta é a última página. Encerre a paginação neste ponto.