Usamos cookies para aprimorar sua experiência em nossos sites e para fins de
publicidade. Política de Privacidade
Aceitar tudo Gerenciar cookies
Introdução
Em alguns momentos é necessário otimizar os dados retornados em uma consulta para o usuário, removendo colunas desnecessárias de uma instrução SELECT e
incluindo condições na sua cláusula WHERE para que o usuário possa obter apenas os dados que realmente precisa visualizar.
Em situações críticas de pequenas empresas, com limitações de hardware e/ou software, além de locais onde o acesso à Internet são limitados também temos a
necessidade de reduzir o conteúdo de tráfego de rede.
Estes são fatores que influenciam na necessidade de tornar a exibição de dados simples e com um pequeno processamento na apresentação dos dados para o
usuário.
Um dos recursos que podem ser utilizados para atender estes requisitos é a Paginação no SQL Server.
O maior objetivo deste artigo é mostrar como um simples script T-SQL pode ser útil desde que ele seja bem implementado.
No final deste artigo vamos avaliar a performance de uma consulta ordenada nas seguintes condições:
1 - Consulta sem paginação no SQL Server (normalmente utilizada por programadores, que deixam a tarefa de "paginar" os dados para um componente "GridView"
ou outro semelhante ;
2 - Consulta com paginação, utilizando ROW_NUMBER (modelo tradicional de paginação em T-SQL);
3 - Consulta com paginação, utilizando as cláusulas OFFSET e FETCH (novo modelo, usado a partir do SQL Server 2012);
https://social.technet.microsoft.com/wiki/pt-br/contents/articles/23533.paginando-uma-consulta-com-sql-server.aspx 1/11
11/9/2020 Paginando uma consulta com SQL Server - artigos TechNet - Brasil (Português) - TechNet Wiki
Veja este script SQL executado na imagem abaixo.
Com estas variáveis definidas, vamos começar com a função ROW_NUMBER, ordenando os dados pelo campo ID_EXAMPLE.
Veja o script abaixo, onde definimos para ser exibida a "página 2" com "5 registros por página":
SELECT * FROM (
SELECT ROW_NUMBER() OVER(ORDER BY ID_EXAMPLE) AS NUMBER,
ID_EXAMPLE, NM_EXAMPLE, DT_CREATE FROM TB_EXAMPLE
) AS TBL
WHERE NUMBER BETWEEN ((@PageNumber - 1) * @RowspPage + 1) AND (@PageNumber * @RowspPage)
ORDER BY ID_EXAMPLE
https://social.technet.microsoft.com/wiki/pt-br/contents/articles/23533.paginando-uma-consulta-com-sql-server.aspx 2/11
11/9/2020 Paginando uma consulta com SQL Server - artigos TechNet - Brasil (Português) - TechNet Wiki
Podemos ver que uma simples operação matemática define o registro inicial e final para cada página.
Como este exemplo utiliza a função ROW_NUMBER, é importante saber que o primeiro registro é a posição "um".
Neste caso como definimos a variável @PageNumber com valor 2 e a variável @RowspPage com valor 5. Então temos na página "2":
- o primeiro registro com o valor do alias "NUMBER" igual a 6
- o último registro desta página igual ao "NUMBER" 10
Segue abaixo o script T-SQL com a mesma lógica utilizada no exemplo anterior.
--CREATING A PAGING WITH OFFSET and FETCH clauses IN "SQL SERVER 2012"
DECLARE @PageNumber AS INT, @RowspPage AS INT
SET @PageNumber = 2
SET @RowspPage = 10
https://social.technet.microsoft.com/wiki/pt-br/contents/articles/23533.paginando-uma-consulta-com-sql-server.aspx 3/11
11/9/2020 Paginando uma consulta com SQL Server - artigos TechNet - Brasil (Português) - TechNet Wiki
Podemos ver que esta operação matemática é tão simples quanto a anterior, porém o processo de controle de dados é diferenciado, devido aos novos recursos do
SQL Server 2012 para a cláusula ORDER BY.
Como este exemplo utiliza a função OFFSET é importante saber que o primeiro registro é a posição "zero".
Neste caso como definimos a variável @PageNumber com valor 2 e a variável @RowspPage com valor 10. Então temos nesta página:
- o primeiro registro na posição 11
- o último registro na posição 20
Como não utilizamos um valor explícito para definir a paginação, a consulta desta tabela torna o trabalho de paginação mais simples e enxuto, mas será que esta nova
consulta utilizando OFFSET é mais eficiente performaticamente do que a consulta utilizando ROW_NUMBER ?
Agora vamos avaliar a performance de uma consulta ordenada nas seguintes condições:
1 - Consulta simples, sem paginação no SQL Server (a paginação é responsabilidade de uma Aplicação ASP.Net, WinForms ou outras).
2 - Consulta com paginação, utilizando ROW_NUMBER (modelo tradicional de paginação em T-SQL);
3 - Consulta com paginação, utilizando as cláusulas OFFSET e FETCH (novo modelo, usado a partir do SQL Server 2012);
-- 1 - SIMPLE QUERY
SELECT * FROM TB_EXAMPLE ORDER BY ID_EXAMPLE
GO
https://social.technet.microsoft.com/wiki/pt-br/contents/articles/23533.paginando-uma-consulta-com-sql-server.aspx 4/11
11/9/2020 Paginando uma consulta com SQL Server - artigos TechNet - Brasil (Português) - TechNet Wiki
Veja o "script 1" executado na imagem abaixo.
Podemos ver que na consulta simples, sem paginação, todos os dados são utilizados pela consulta e não apenas os dados que o usuário necessita.
Isto é uma enorme perda de recurso: processamento, I/O em disco e memória consumida pela instância no servidor SQL.
Além disto, o tempo de apresentação dos dados para o usuário é muito maior porque é necessário preparar o conteúdo para paginar os dados pela interface do
usuário (UI). Em grandes volumes de dados e com a concorrência de uso destes dados, isto pode se tornar um transtorno.
Vamos ver o custo do Plano de Execução desta consulta dentro do SQL Server.
O Plano de Execução mostra o custo em paralelo devido à falta de um índice na tabela numa estrutura simplificada.
https://social.technet.microsoft.com/wiki/pt-br/contents/articles/23533.paginando-uma-consulta-com-sql-server.aspx 5/11
11/9/2020 Paginando uma consulta com SQL Server - artigos TechNet - Brasil (Português) - TechNet Wiki
Para analisar o desempenho de cada consulta, vamos obter 3 amostras de execução e comparar apenas a Estatística de Tempo ("Client processing time" e "Total
execution time") com melhor performance.
No caso da primeira consulta (script 1), que é um SELECT simples, o melhor tempo de execução possui:
O tráfego de rede é pequeno para o cliente mas muito elevado para o servidor:
Além deste tempo excessivo, será necessário criar um processo de paginação assim que os dados forem recebidos pela aplicação Client/Server ou Web.
Desta forma, o tempo de processamento dos dados e apresentação do conteúdo para o usuário será ainda maior.
Vamos executar agora o script T-SQL utilizando ROW_NUMBER para a paginação de dados. Lembrando que este modelo de paginação em consultas funciona a
partir do SQL Server 2000 até as atuais versões do SQL Server 2012.
SELECT * FROM (
SELECT ROW_NUMBER() OVER(ORDER BY ID_EXAMPLE) AS Numero,
ID_EXAMPLE, NM_EXAMPLE , DT_CREATE FROM TB_EXAMPLE
) AS TBL
WHERE Numero BETWEEN ((@PageNumber - 1) * @RowspPage + 1) AND (@PageNumber * @RowspPage)
ORDER BY ID_EXAMPLE
GO
https://social.technet.microsoft.com/wiki/pt-br/contents/articles/23533.paginando-uma-consulta-com-sql-server.aspx 6/11
11/9/2020 Paginando uma consulta com SQL Server - artigos TechNet - Brasil (Português) - TechNet Wiki
Veja o "script 2" executado na imagem abaixo.
Podemos ver que na consulta utilizando ROW_NUMBER, a paginação fornece apenas os dados utilizados pela consulta que o usuário necessita.
Isto torna a consulta dos dados mais objetiva, reduzindo: processamento, I/O em disco e memória consumida pela instância no servidor SQL.
O tempo de apresentação dos dados para o usuário também diminui porque o conteúdo da consulta já está pronto para exibição dos dados pela interface do usuário
(UI).
Vamos ver o custo do Plano de Execução desta consulta dentro do SQL Server.
Veja o Plano de Execução do "script 2" na imagem abaixo (clique na imagem para ampliar)
Neste Plano de Execução, podemos ver uma estrutura mais complexa onde o SQL Server organiza a obtenção apenas dos dados solicitados na consulta.
Apesar deste processamento ser muito maior do que o exibido no Plano de Execução do "script 1", o tempo de execução será menor devido a quantidade de dados
que será retornado ao usuário na aplicação.
Vamos ver as 3 amostras de execução do "script 2", para que possamos comparar este tempo de execução.
https://social.technet.microsoft.com/wiki/pt-br/contents/articles/23533.paginando-uma-consulta-com-sql-server.aspx 7/11
11/9/2020 Paginando uma consulta com SQL Server - artigos TechNet - Brasil (Português) - TechNet Wiki
No caso da segunda consulta (script 2 - com ROW_NUMBER), o melhor tempo de execução possui:
O tráfego de rede se torna maior para o cliente mas é reduzido consideravelmente para o servidor:
Além deste tempo reduzido, com pouco mais de 10 vezes o tempo da consulta no "script 1", podemos ver facilmente que a redução de linhas retornadas pela
consulta também refletem na diminuição da quantidade de Bytes enviados do Servidor para o Cliente.
Desta forma, o tempo de processamento dos dados e apresentação do conteúdo para o usuário diminui consideravelmente, além de reduzir o tráfego de rede entre o
servidor e a Aplicação Cliente.
Vamos executar agora o script T-SQL utilizando OFFSET/FETCH para a paginação de dados. Lembrando que este modelo de paginação em consultas funciona
apenas com as atuais versões do SQL Server 2012.
https://social.technet.microsoft.com/wiki/pt-br/contents/articles/23533.paginando-uma-consulta-com-sql-server.aspx 8/11
11/9/2020 Paginando uma consulta com SQL Server - artigos TechNet - Brasil (Português) - TechNet Wiki
Podemos ver que na consulta utilizando OFFSET/FETCH, a paginação fornece apenas os dados utilizados pela consulta que o usuário necessita, semelhante ao
processo do "script 2" (que utiliza ROW_NUMBER).
A consulta dos dados também é reduzida, mas seu processo é mais simplificado.
Vamos ver o custo do Plano de Execução desta consulta dentro do SQL Server.
https://social.technet.microsoft.com/wiki/pt-br/contents/articles/23533.paginando-uma-consulta-com-sql-server.aspx 9/11
11/9/2020 Paginando uma consulta com SQL Server - artigos TechNet - Brasil (Português) - TechNet Wiki
Neste Plano de Execução, podemos ver uma estrutura mais simples onde o SQL Server organiza a obtenção apenas dos dados solicitados na consulta.
Apesar deste processamento ser semelhante ao exibido no Plano de Execução do "script 1", o tempo de execução será menor devido à quantidade de dados que será
retornado ao usuário na aplicação.
Vamos ver as 3 amostras de execução do "script 3", para que possamos comparar este tempo de execução.
No caso da terceira consulta (script 3 - com OFFSET/FETCH), o melhor tempo de execução possui:
O tráfego de rede se torna maior para o cliente mas é reduzido consideravelmente para o servidor:
Além deste tempo reduzido, um pouco melhor do que o tempo da consulta no "script 2" (ROW_NUMBER), podemos ver a redução nos Bytes enviados e recebidos,
que consequentemente impacta na redução do tempo de execução de todo o processo.
Conclusão
Podemos ver que a paginação de uma instrução SELECT é simples de ser criada e pode ser considerada um excelente recursos para grandes quantidades de dados.
A otimização de processamento de dados pelo T-SQL tem um ganho considerável tanto utilizando o ROW_NUMBER como na utilização de OFFSET/FETCH, porém
levando em consideração a análise destes dados podemos afirmar que a consulta do "script 3"(que utiliza OFFSET/FETCH) pode ser a melhor opção em grandes
volumes de registros, desde que você utilize um servidor SQL Server 2012.
Referências
ROW_NUMBER (Transact-SQL)
Cláusula ORDER BY (Transact-SQL) - Limitando o número de linhas retornadas
Veja Também
Wiki: Portal dos Portais TechNet Wiki
How to insert Serial Numbers in repeater and gridview in ASP.NET
SQL Server: How to Find the First Available Timeslot for Scheduling
Portal Transact-SQL
Outros Idiomas
Paging a Query with SQL Server (en-US)
https://social.technet.microsoft.com/wiki/pt-br/contents/articles/23533.paginando-uma-consulta-com-sql-server.aspx 11/11