복붙노트

[SQL] SQL 성능 : WHERE WHERE (ROW_NUMBER) 대

SQL

SQL 성능 : WHERE WHERE (ROW_NUMBER) 대

나는 테이블에 m 번째 기록에 n 번째를 얻을 싶어, 솔루션 아래 2의 최선의 선택은 무엇인가 :

해결 방법 1 :

    SELECT * FROM Table WHERE ID >= n AND ID <= m

해결 방법 2 :

    SELECT * FROM 
                (SELECT *, 
                        ROW_NUMBER() OVER (ORDER BY ID) AS row 
                 FROM Table 
                )a 
    WHERE row >= n AND row <= m

해결법

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

    1.제 2 대답은 최고의 선택이 될 것입니다. 그것은 계정에 당신이 당신의 ID 컬럼에 구멍을 가질 수 있다는 사실을합니다. 나는 CTE하지만 대신 하위 쿼리로 다시 작성할 것 ...

    제 2 대답은 최고의 선택이 될 것입니다. 그것은 계정에 당신이 당신의 ID 컬럼에 구멍을 가질 수 있다는 사실을합니다. 나는 CTE하지만 대신 하위 쿼리로 다시 작성할 것 ...

    ;WITH MyCTE AS
    (SELECT  *,  
             ROW_NUMBER() OVER (ORDER BY ID) AS row  
    FROM     Table)
    SELECT   *
    FROM     MyCTE
    WHERE    row >= @start 
             AND row <= @end
    
  2. ==============================

    2.다른 하나는 이미 지적한 바와 같이, 쿼리는 다른 결과를 반환하고 사과와 오렌지를 비교한다.

    다른 하나는 이미 지적한 바와 같이, 쿼리는 다른 결과를 반환하고 사과와 오렌지를 비교한다.

    그러나 근본적인 질문 남아 : 빠른 : 키 집합 구동 페이징 또는 ROWNUMBER는 페이징을 구동?

    키 집합 구동 페이징은 지난 표시된 페이지의 상단과 하단 키를 기억하고, 상부 / 마지막 키 집합을 기반으로, 행의 다음 또는 이전 설정을 요구에 의존한다 :

    다음 페이지 :

    select top (<pagesize>) ...
    from <table>
    where key > @last_key_on_current_page
    order by key;
    

    이전 페이지 :

    select top (<pagesize>)
    from <table>
    where key < @first_key_on_current_page
    order by key desc;
    

    이 방법은 ROW_NUMBER 접근 방식을 통해, 또는 MySQL의에 해당 LIMIT 접근 방식을 통해 두 가지 장점이 있습니다 :

    그러나이 방법은 구현하기가 어렵 평균 프로그래머가 이해하기 어렵고 도구에서 지원되지 않습니다.

    이 LINQ 쿼리 소개 된 일반적인 방법입니다 :

    select ...
    from (
      select ..., row_number() over (...) as rn
      from table)
    where rn between @firstRow and @lastRow;
    

    (또는 유사한 쿼리를 사용하여 TOP) 이 방법은 쉽게 구현할 수 있으며 (특히 Linq에으로 제한 할 및 .Take 운영자에 의해) 툴에 의해 지원됩니다. 그러나이 방법은 행을 계산하기 위해 인덱스를 스캔 보장된다. 이 방법은 1 페이지에 대한 매우 빠른 일반적으로 작동하고 점차적으로 하나가 더 높은 페이지 번호로 이동으로 속도가 느려집니다.

    이 솔루션 보너스로서, (단순히 OVER 절을 변경) 정렬 순서를 변경하는 것은 매우 쉽습니다.

    전체적으로 ROW_NUMBER () 기반 솔루션의 용이성을 감안 그들이에서 Linq에있는 지지체, 적당한 데이터에 대해 임의의 명령을 사용하는 단순은 ROW_NUMBER 기반 솔루션이 적합 설정한다. 크고 매우 큰 데이터 세트의 경우, ROW_NUMBER ()는 심각한 성능 문제가 발생할 수 있습니다.

    고려해야 할 또 다른 점은 액세스의 명확한 패턴이 배 종종 있다는 것입니다. 종종 처음 몇 페이지는 뜨거운 10 이후 페이지는 기본적으로 조회되지 않습니다 (예. 가장 최근의 게시물). 이 경우, 하단 페이지 (많은 수의 행이 시작 결과 행을 얻기 위해 계산해야하는 디스플레이 페이지)를 방문 ROW_NUMBER 발생 페널티는 ()도 무시 될 수 있습니다.

    그리고 마지막으로, 키 집합 매김은 ROW_NUMBER ()를 쉽게 수용 할 수있는 사전 탐색에 좋은 곳입니다. 대신에 페이지 번호를 사용하는 사용자는 알파벳 문자와 같은 특정 앵커로 이동할 수있는 사전 탐색이다. 사이드 바 같은 접촉 롤로 덱스되는 전형적인 예를 들어, 당신은 M을 클릭하고 첫 번째 고객 이름으로 이동하는 M.로 시작

  3. ==============================

    3.그들은 서로 다른 쿼리입니다.

    그들은 서로 다른 쿼리입니다.

    대리 키 ID를 가정되고, 그 틈을 가질 수있다. ROW_NUMBER는 연속 될 것입니다.

    당신은 보장 할 수있는 경우는, 데이터에 틈이 없다 후 1 일 나는이 인덱스를 바란다 것 때문에 ,. 제 2 하나는하지만 더 "올바른"입니다.

  4. from https://stackoverflow.com/questions/3212692/sql-performance-where-vs-whererow-number by cc-by-sa and MIT license