Paginar os resultados da pesquisa

Os aplicativos da Web geralmente paginam os dados conforme são apresentados aos usuários. O usuário final recebe uma página de resultados e, quando navega para a próxima página, a próxima lote de resultados é recuperado e apresentado. Nesta página, descrevemos como adicionar paginação para pesquisar os resultados ao realizar uma pesquisa de texto completo no Spanner.

Visão geral

Há duas maneiras de implementar consultas paginadas no Spanner: paginação baseada em chaves (recomendado) e Paginação com base em deslocamento.

A paginação baseada em chaves é um método para recuperar resultados de pesquisa em páginas menores blocos gerenciáveis, garantindo resultados consistentes em todas as solicitações. Um identificador único (a "chave") do último resultado de uma página é usado como ponto de referência para buscar o próximo conjunto de resultados.

Em geral, o Spanner recomenda o uso de paginação baseada em chaves. Embora a paginação baseada em deslocamento seja mais fácil de implementar, ela tem duas desvantagens significativas:

  1. Maior custo de consulta:a paginação baseada em deslocamento recupera e descarta os mesmos resultados, aumentando os custos e desempenho.
  2. Resultados inconsistentes: em consultas paginadas, cada página costuma ser recuperados em um carimbo de data/hora de leitura diferente. Por exemplo, a primeira página pode vir de uma consulta às 13h, e a próxima de uma consulta às 13h10. Isso significa que os resultados da pesquisa podem mudar entre as consultas, resultando em resultados inconsistentes nas páginas.

A paginação baseada em chave, por outro lado, usa um identificador exclusivo (chave) do último resultado de uma página para buscar o próximo conjunto de resultados. Isso garante que recuperação eficiente e resultados consistentes, mesmo se os dados subjacentes mudarem.

Para fornecer estabilidade nos resultados da página, o aplicativo pode emitir todas as consultas para páginas diferentes no mesmo carimbo de data/hora. No entanto, isso pode falhar se a consulta excede a retenção de versão período (o padrão é 1 hora). Por exemplo, essa falha acontece se version_gc for uma hora e o usuário final tiver buscado os primeiros resultados às 13h e clicado em Próxima às 15h.

Usar a paginação baseada em chaves

A paginação baseada em chaves lembra o último item da página anterior e o usa como ponto de partida para a consulta da próxima página. Para isso, a consulta deve retornar as colunas especificadas na cláusula ORDER BY e limitar o número de linhas usando LIMIT.

Para que a paginação baseada em chaves funcione, a consulta deve ordenar os resultados de acordo com alguns critérios total do pedido. A maneira mais fácil de conseguir uma é escolher qualquer ordem total e adicionar colunas de desempate, se necessário. Na maioria dos casos, a ordem total é a classificação do índice de pesquisa e a combinação exclusiva de colunas é a chave primária da tabela base.

Usando nosso esquema de amostra Albums, para a primeira página, a consulta é semelhante a esta:

SELECT AlbumId, ReleaseTimestamp
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY ReleaseTimestamp DESC, AlbumId
LIMIT 10;

O AlbumId é o desempatador, já que ReleaseTimestamp não é uma chave. podem ser dois álbuns diferentes com o mesmo valor para ReleaseTimestamp.

Para retomar, o aplicativo executa a mesma consulta novamente, mas com uma cláusula WHERE que restringe os resultados da página anterior. A condição adicional precisa considerar a direção da chave (crescente ou decrescente), desempatadores, e a ordem dos valores NULL para colunas anuláveis.

Em nosso exemplo, AlbumId é a única coluna de chave (em ordem crescente) e não pode ser NULL, então a condição é a seguinte:

SELECT AlbumId, ReleaseTimestamp
FROM Albums
WHERE (ReleaseTimestamp < @last_page_release_timestamp
       OR (ReleaseTimestamp = @last_page_release_timestamp
           AND AlbumId > @last_page_album_id))
      AND SEARCH(AlbumTitle_Tokens, @p)
ORDER BY ReleaseTimestamp DESC, AlbumId ASC
LIMIT @page_size;

O Spanner interpreta esse tipo de condição como seekable. Isso significa que o Spanner não lê o índice dos documentos que você está filtrando. É essa otimização que torna a paginação baseada em chaves muito mais eficiente do que a paginação baseada em deslocamento.

Usar a paginação com base no deslocamento

A paginação baseada em deslocamento aproveita as cláusulas LIMIT e OFFSET da consulta SQL. para simular páginas. O valor LIMIT indica o número de resultados por página. O valor OFFSET é definido como zero para a primeira página, o tamanho da página para a segunda e o dobro do tamanho da página para a terceira.

Por exemplo, a consulta a seguir busca a terceira página, com um tamanho de página de 50:

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")
ORDER BY ReleaseTimestamp DESC, AlbumId
LIMIT 50 OFFSET 100;

Observações sobre o uso:

  • A cláusula ORDER BY é altamente recomendada para garantir o ordenamento consistente entre as páginas.
  • Nas consultas de produção, use parâmetros de consulta em vez de constantes para especificar LIMIT e OFFSET e tornar o armazenamento em cache de consultas mais eficiente. Para mais informações, consulte Parâmetros de consulta.

A seguir