AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 32884
Accepted
LCJ
LCJ
Asked: 2013-01-15 06:18:11 +0800 CST2013-01-15 06:18:11 +0800 CST 2013-01-15 06:18:11 +0800 CST

Como a paginação funciona com ROW_NUMBER no SQL Server?

  • 772

Eu tenho uma Employeetabela 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 vejo como um problema é - a tabela derivada tblEmployeeseleciona todos os registros na Employeetabela (para criar os MyRowNumbervalores).

Eu acho que isso causa a seleção de todos os registros na Employeetabela.

Será que realmente funciona assim? Ou o SQL Server é otimizado para selecionar apenas os 5 registros da Employeetabela original também?

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 
sql-server performance
  • 5 5 respostas
  • 50044 Views

5 respostas

  • Voted
  1. Best Answer
    Aaron Bertrand
    2013-01-15T07:13:54+08:002013-01-15T07:13:54+08:00

    Uma alternativa para testar pode ser:

    ;WITH x AS (SELECT EmpID, k = ROW_NUMBER() OVER (ORDER BY EmpID) FROM dbo.Emp)
    SELECT e.columns
    FROM x INNER JOIN dbo.Emp AS e
    ON x.EmpID = e.EmpID
    WHERE x.k BETWEEN (((@Index - 1) * @PageSize) + 1) AND @Index * @PageSize
    ORDER BY ...;
    

    Sim, você atinge a tabela duas vezes, mas no CTE onde você varre a tabela inteira, você 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 continuação da discussão:

    http://www.sqlservercentral.com/Forums/Topic672980-329-1.aspx

    No SQL Server 2012, é claro, você pode usar a nova sintaxe OFFSET/ :FETCH NEXT

    ;WITH x AS 
    (
      SELECT EmpID FROM dbo.Emp
        ORDER BY EmpID
        OFFSET  @PageSize * (@Index - 1) ROWS
        FETCH NEXT @PageSize ROWS ONLY
    )
    SELECT e.columns
    FROM x INNER JOIN dbo.Emp AS e
    ON x.EmpID = e.EmpID
    ORDER BY ...; 
    

    Eu também escrevi sobre isso com mais detalhes aqui:

    • SQL Server v.Next (Denali): Usando a cláusula OFFSET (paginação)
    • Paginação com OFFSET / FETCH : Uma maneira melhor
    • 20
  2. JeffO
    2013-01-15T06:49:18+08:002013-01-15T06:49:18+08:00

    Embora você possa não conhecer o mecanismo por trás disso, você pode testar isso comparando o desempenho de sua consulta com: select * from Employee.

    As versões mais recentes do SQL Server fazem um bom trabalho de otimização, mas isso pode depender de vários fatores.

    O desempenho da sua função ROW_NUMBER será orientado pela cláusula Order By. No seu exemplo, a maioria acharia que EmpID é a chave primária.

    Existem algumas cláusulas where que são tão complexas e/ou mal codificadas ou indexadas, você pode ser melhor apenas retornar todo o conjunto de dados (é raro e pode ser corrigido). Usar BETWEEN tem problemas.

    Antes de assumir que seria melhor retornar todas as linhas ao seu aplicativo e deixá-lo descobrir, você deve trabalhar na otimização de sua consulta. Confira as estimativas. Pergunte ao Analisador de Consultas. Teste algumas alternativas.

    • 2
  3. Sam Raj
    2013-08-24T04:06:35+08:002013-08-24T04:06:35+08:00

    Eu sei que a pergunta é sobre row_number(), mas eu quero adicionar um novo recurso do sql server 2012. No sql server 2012 novo recurso OFFSET Fetch introduzido em seguida e é muito rápido do que row_number(). Eu usei e me deu 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/

    que é útil. Espero que ajude você também para implementar novos recursos ....

    • 2
  4. user3688672
    2014-06-17T11:15:24+08:002014-06-17T11:15:24+08:00

    Eu não acho que avalia para retornar todas as linhas na tabela original. O SQL Server 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. Então, com certeza não recebe todas as linhas. No entanto, é mais lento do que apenas buscar as primeiras cinco linhas, provavelmente devido ao tempo gasto no pedido

    • -2
  5. Agnel Amodia
    2018-01-30T19:59:14+08:002018-01-30T19:59:14+08:00
    DECLARE @PageIndex int;
    DECLARE @PageSize int;
    SET @PageIndex = 4;
    SET @PageSize = 5;
    ;With ranked AS   --- Or you can make it a view
    (
       SELECT ROW_NUMBER() OVER(ORDER BY IdentityId) AS RowNum,  *
       FROM logeventnew
    )
    SELECT *   --Your fields here
    FROM Ranked
    WHERE RowNum BETWEEN ((@PageIndex - 1) * @PageSize + 1)
        AND (@PageIndex * @PageSize)
    ORDER BY IdentityId
    
    • -2

relate perguntas

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Conceder acesso a todas as tabelas para um usuário

    • 5 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve