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: