복붙노트

[SQL] SQL Server 2008의 페이징 방법?

SQL

SQL Server 2008의 페이징 방법?

나는 기록의 가능성이 큰 목록과 함께 작업을하고 난 내가 대신 사용자가 페이지를 (같은 1 ~ 10)을 선택하고 그에 따라 레코드를 표시하도록하려면, 전체 목록을 선택하지 않도록하는 방법을 인터넷 검색을 했어요.

말은 1000 개 기록을 위해 나는 5 페이지의 사용자 클릭, 그것은 41에서 50로 기록을 보여줍니다 경우 먼저 표시됩니다 (10 개) 기록을 각각 가장 최근의 10 개 개의 레코드의 100 페이지가됩니다.

그 다음 쿼리 행 수에 따라 각 레코드에 행 번호를 추가하는 좋은 아이디어인가? 너무 많은 오버 헤드없이 페이징 결과를 달성하는 더 좋은 방법이 있나요? 지금까지 여기에 설명 된대로 그 방법은 가장 유망한를 보면 :

http://developer.berlios.de/docman/display_doc.php?docid=739&group_id=2899

http://www.codeproject.com/KB/aspnet/PagingLarge.aspx

해결법

  1. ==============================

    1.다음 T-SQL 저장 프로 시저 호출의 매우 효율적인 구현입니다. 는 SQL 최적화는 매우 빠르게 최초의 ID를 찾을 수 있습니다. ROWCOUNT의 사용이 결합, 당신은 CPU 효율적인 읽기 효율적으로 모두 인 접근 방식을 가지고있다. 많은 수의 행이있는 테이블의 경우, 확실히 내가 임시 테이블이나 테이블 변수를 사용하여 보았으므로 어떤 접근 방식을 친다.

    다음 T-SQL 저장 프로 시저 호출의 매우 효율적인 구현입니다. 는 SQL 최적화는 매우 빠르게 최초의 ID를 찾을 수 있습니다. ROWCOUNT의 사용이 결합, 당신은 CPU 효율적인 읽기 효율적으로 모두 인 접근 방식을 가지고있다. 많은 수의 행이있는 테이블의 경우, 확실히 내가 임시 테이블이나 테이블 변수를 사용하여 보았으므로 어떤 접근 방식을 친다.

    NB :이 예에서 순차적 ID 열을 사용하고 있지만, 코드 페이지 정렬에 적합한 임의의 컬럼에서 작동합니다. 또한, 칼럼의 순서 바꿈 코드 행의 개수보다 열 값을 선택으로 결과에 영향을주지 않는 사용된다.

    편집 : 당신은 가능성이 아닌 고유 한 값으로 열을 정렬하는 경우 (예 : 성), 다시 정렬 값이 고유하게 ORDER BY 절에 두 번째 열을 추가합니다.

    CREATE  PROCEDURE dbo.PagingTest
    (
        @PageNumber int,
        @PageSize int
    )
    AS
    
    DECLARE @FirstId int, @FirstRow int
    
    SET @FirstRow = ( (@PageNumber - 1) * @PageSize ) + 1
    SET ROWCOUNT @FirstRow
    
    -- Add check here to ensure that @FirstRow is not
    -- greater than the number of rows in the table.
    
    SELECT   @FirstId = [Id]
    FROM     dbo.TestTable
    ORDER BY [Id]
    
    SET ROWCOUNT @PageSize
    
    SELECT   *
    FROM     dbo.TestTable
    WHERE    [Id] >= @FirstId
    ORDER BY [Id]
    
    SET ROWCOUNT 0
    GO 
    
  2. ==============================

    2.두 ROW_NUMBER () 열이있는 CTE를 사용하는 경우 - 하나 오름차순, 하나의 내림차순으로 정렬, 두 ROW_NUMBER 열을 추가하여 페이징뿐만 아니라 전체 레코드에 대해 행 번호를 얻을.

    두 ROW_NUMBER () 열이있는 CTE를 사용하는 경우 - 하나 오름차순, 하나의 내림차순으로 정렬, 두 ROW_NUMBER 열을 추가하여 페이징뿐만 아니라 전체 레코드에 대해 행 번호를 얻을.

    create procedure get_pages(@page_number int, @page_length int)
    as
        set nocount on;
    
        with cte as
        (
            select 
                Row_Number() over (order by sort_column desc) as row_num
                ,Row_Number() over (order by sort_column) as inverse_row_num
                ,id as cte_id
            From my_table
        )
        Select 
            row_num+inverse_row_num as total_rows
            ,*  
        from CTE inner join my_table
            on cte_id=df_messages.id
        where row_num between 
            (@page_number)*@page_length 
            and (@page_number+1)*@page_length
        order by rownumber
    
  3. ==============================

    3.ROW_NUMBER () OVER () 순위 기능이 페이지를 수행하는 데 사용할 수있는 방법을 다른 사람은 설명했다. 표준 SQL에 대한 SQL 서버 2012 마지막 포함 지원이 오프셋 언급 그것의 가치는 .. 절을 FETCH :

    ROW_NUMBER () OVER () 순위 기능이 페이지를 수행하는 데 사용할 수있는 방법을 다른 사람은 설명했다. 표준 SQL에 대한 SQL 서버 2012 마지막 포함 지원이 오프셋 언급 그것의 가치는 .. 절을 FETCH :

    SELECT first_name, last_name, score
    FROM players
    ORDER BY score DESC
    OFFSET 40 ROWS FETCH NEXT 10 ROWS ONLY
    

    당신이 문제를 SQL 서버 2012 이전 버전과의 호환성을하지 않는 사용하는 경우가 코너의 경우 SQL Server가 더 최적으로 실행됩니다, 당신은 아마이 절을 선호한다.

    SQL에서 페이징을 수행 할 수있는 완전히 다른, 훨씬 더 빠른 방법이있다. 이것은 종종 여기이 블로그 게시물에 설명 된대로이 "방법을 추구"라고합니다.

    SELECT TOP 10 first_name, last_name, score
    FROM players
    WHERE (score < @previousScore)
       OR (score = @previousScore AND player_id < @previousPlayerId)
    ORDER BY score DESC, player_id DESC
    

    @previousScore 및 @previousPlayerId 값은 이전 페이지에서 마지막 레코드의 각각의 값입니다. 이것은 당신이 "다음"페이지를 가져 오지 수 있습니다. 방향 BY 순서는 ASC 인 경우, 단순히 대신> 사용합니다.

    위의 방법을 사용하면 즉시 먼저 이전 (40 개) 기록을 인출하지 않고 4 페이지로 이동할 수 없습니다. 그러나 종종, 당신은 지금까지 어쨌든 점프하고 싶지 않아요. 대신, 당신은 당신의 색인에 따라 일정 시간에 데이터를 가져올 수있을 훨씬 빠른 쿼리를 얻을. 또한, 페이지가 "안정적"유지, 아무리 경우 (예를 들어, 1 페이지, 당신은 4 페이지에있는 동안) 기본 데이터가 변경됩니다.

    이 게으른 로딩 더 많은 웹 애플리케이션의 데이터 예를 들어, 페이징을 구현하는 가장 좋은 방법입니다.

    참고가 "방법을 추구"도 키 집합 페이징이라고합니다.

  4. ==============================

    4.이 같은 시도 :

    이 같은 시도 :

    declare @page int = 2
    declare @size int = 10
    
    declare @lower int =  (@page - 1) * @size
    declare @upper int =  (@page    ) * @size
    
    select * from (
    select 
        ROW_NUMBER() over (order by some_column) lfd,
    * from your_table
    ) as t
     where lfd between @lower and @upper
     order by some_column
    
  5. ==============================

    5.여기에 TOP을 사용하여의 RoadWarrior의 코드 @의 업데이트 버전입니다. 성능이 매우 빠르고 동일하다. 당신이 TestTable.ID에 인덱스를 가지고 있는지 확인

    여기에 TOP을 사용하여의 RoadWarrior의 코드 @의 업데이트 버전입니다. 성능이 매우 빠르고 동일하다. 당신이 TestTable.ID에 인덱스를 가지고 있는지 확인

    CREATE PROC dbo.PagingTest
        @SkipRows int,
        @GetRows int
    AS
    DECLARE @FirstId int
    
    SELECT   TOP (@SkipRows) 
             @FirstId = [Id]
    FROM     dbo.TestTable
    ORDER BY [Id]
    
    SELECT   TOP (@GetRows) *
    FROM     dbo.TestTable
    WHERE    [Id] >= @FirstId
    ORDER BY [Id]
    
    GO 
    
  6. ==============================

    6.이 시도

    이 시도

    Declare @RowStart int, @RowEnd int;
    
    
    SET @RowStart = 4;
    SET @RowEnd = 7; 
    
    With MessageEntities As 
    (
        Select ROW_NUMBER() Over (Order By [MESSAGE_ID]) As Row, [MESSAGE_ID]
        From [TBL_NAFETHAH_MESSAGES]
    )
    Select  m0.MESSAGE_ID, m0.MESSAGE_SENDER_NAME,
            m0.MESSAGE_SUBJECT, m0.MESSAGE_TEXT
    From MessageEntities M
        Inner Join [TBL_NAFETHAH_MESSAGES] m0 on M.MESSAGE_ID = m0.MESSAGE_ID
    Where M.Row Between @RowStart AND @RowEnd
    Order By M.Row Asc
    GO
    
  7. ==============================

    7.왜 권장 솔루션을 사용하지 :

    왜 권장 솔루션을 사용하지 :

  8. from https://stackoverflow.com/questions/4358253/sql-server-2008-paging-methods by cc-by-sa and MIT license