loading...
Cover image for Dica Rápida: Paginando no MSSQL considerando escala

Dica Rápida: Paginando no MSSQL considerando escala

wsantosdev profile image William Santos ・2 min read

Olá!

Este post é uma breve continuação do Dica Rápida: Paginando no MSSQL com Offset e Fetch.

Antes de começar, gostaria de agradecer aos colegas Rafael Ponte e Renato Todorov que fizeram considerações sobre alto volume de dados na Dica Rápida anterior, dando origem a esta continuação! Obrigado, pessoal!

Vamos lá?

Muito embora, para cenários mais simples, com baixo volume de dados, o uso de Offset e Fetch seja suficiente, quando precisamos trabalhar com grandes volumes, a história muda.

Explico.

No último post disse que a instrução Offset vai pular a quantidade de linhas informada. Certo? Pois é! Mas para que o banco saiba quantas e quais linhas pular, ele precisa percorrê-las primeiro. Ou seja, o banco vai percorrer todas as linhas que respeitem o critério BirthDate e, em seguida, vai usar as instruções Offset e Fetch para decidir quais linhas retornar.

E é aí que mora o problema porque, quanto mais linhas sua tabela tiver, e quanto maior for o Offset informado, maior será o número de linhas que deverá ser percorrido antes de retornar a quantidade solicitada pelo uso do Fetch! E este é um baita prejuízo para a performance se for preciso paginar milhares de registros.

Mas, então, como resolver isso? Por incrível que pareça, é fácil! A solução se chama keyset pagination (ou cursor pagination)!

Em vez de informarmos ao banco em qual página estamos, informaremos o último Id que lemos, retornaremos apenas os registros de Id superior, e assim eliminamos o esforço do Offset.

O código anterior seria convertido para o seguinte:

SELECT TOP (@PageSize)
    Id,
    FirstName, 
    LastName
FROM 
    Customer
WHERE 
    Id > @LastId -- Ou Id < @LastId se a intenção for retroceder uma página
AND
    BirthDate >= '2000-01-01'
ORDER BY
    Id

Aparentemente não mudou muita coisa. Não é? Mas, do ponto de vista do banco, essa simples mudança representa um enorme alívio porque, desta forma, não precisamos mais instruir o banco a subdividir a consulta com todos os resultados que atendam ao critério BirthDate informado, pois a informação do TOP no SELECT, e do último Id conhecido na cláusua WHERE, são o suficiente para instruir o banco sobre a partir de qual linha ele deve começar, e até quantas linhas ele precisa percorrer.

Nota: A coluna Id pode combinada com, ou substituída por, qualquer coluna indexada.

Legal. Né?

Gostou? Me deixe saber pelos indicadores. Dúvidas? Me envie pelos comentários que responderei assim que puder.

Até a próxima!

Referências:

Please Don't Use OFFSET and LIMIT For Your Pagination

Posted on by:

wsantosdev profile

William Santos

@wsantosdev

Um desenvolvedor que brinca com .NET e se diverte um pouco com outras linguagens e tecnologias. { A software developer who plays with .NET and have some fun with other languages and technologies. }

Discussion

pic
Editor guide
 

Massa demais essas dicas William, agregam muito, nunca tinha ouvido falar do termo keyset pagination, mais uma ferramenta na caixinha! Obrigado!

 

Eu que te agradeço pelo feedback, Vinícius! Legal saber que está sendo útil e que está acompanhando.
Valeu! o/