Eu tenho uma Employee
tabela que tem um milhão de registros. Eu tenho o seguinte SQL para paginar dados em um aplicativo da web. Está funcionando bem. No entanto, o que eu vejo como um problema é - a tabela derivada tblEmployee
seleciona todos os registros da Employee
tabela (para criar os MyRowNumber
valores).
Eu acho que isso causa a seleção de todos os registros na Employee
tabela.
Isso realmente funciona? Ou o SQL Server é otimizado para selecionar também apenas os 5 registros da Employee
tabela original ?
DECLARE @Index INT;
DECLARE @PageSize INT;
SET @Index = 3;
SET @PageSize = 5;
SELECT * FROM
(SELECT ROW_NUMBER() OVER (ORDER BY EmpID asc) as MyRowNumber,*
FROM Employee) tblEmployee
WHERE MyRowNumber BETWEEN ( ((@Index - 1) * @PageSize )+ 1) AND @Index*@PageSize
Respostas:
Uma alternativa ao teste pode ser:
Sim, você bate na tabela duas vezes, mas no CTE, onde você varre a tabela inteira, está apenas pegando a chave, não TODOS os dados. Mas você realmente deve olhar para este artigo:
http://www.sqlservercentral.com/articles/T-SQL/66030/
E a discussão de acompanhamento:
http://www.sqlservercentral.com/Forums/Topic672980-329-1.aspx
No SQL Server 2012, é claro, você pode usar a nova
OFFSET
/FETCH NEXT
sintaxe:fonte
Embora você não conheça o mecanismo por trás dele, você mesmo pode testar isso comparando o desempenho da sua consulta com: selecione * em Funcionário.
As versões mais recentes do SQL Server fazem um ótimo trabalho de otimização, mas isso pode depender de vários fatores.
O desempenho da sua função ROW_NUMBER será determinado pela cláusula Order By. No seu exemplo, a maioria pensaria que o EmpID é a chave primária.
Existem algumas cláusulas where que são tão complexas e / ou mal codificadas ou indexadas, é melhor retornar apenas o conjunto de dados inteiro (é raro e pode ser corrigido). O uso de BETWEEN tem problemas.
Antes de assumir que seria melhor retornar todas as linhas para o seu aplicativo e deixá-lo descobrir, você deve otimizar sua consulta. Verifique as estimativas. Pergunte ao Query Analyzer. Teste algumas alternativas.
fonte
Eu sei que a pergunta é sobre row_number (), mas quero adicionar um novo recurso do sql server 2012. No sql server 2012, o novo recurso OFFSET Fetch é apresentado a seguir e é muito rápido que o row_number (). Eu usei e me dá um bom resultado espero que vocês também preencham a mesma experiência.
Encontrei um exemplo em http://blogfornet.com/2013/06/sql-server-2012-offset-use/
o que é útil. Espero que também o ajude a implementar novos recursos ....
fonte
Eu não acho que ele avalia retornar todas as linhas na tabela original. O servidor SQL otimiza. Caso contrário, levará muito tempo para selecionar um milhão de entradas. Atualmente, estou usando isso e é muito mais rápido do que selecionar todas as linhas. Portanto, com certeza não obtém todas as linhas. No entanto, é mais lento do que apenas buscar as cinco primeiras linhas, provavelmente devido ao tempo gasto no pedido
fonte
fonte