[performance] OFFSET / FETCH NEXT에서 총 행 수 가져 오기

따라서 웹 사이트에서 페이징을 구현하려는 여러 레코드를 반환하는 함수가 있습니다. 이 작업을 수행하기 위해 SQL Server 2012에서 Offset / Fetch Next를 사용하는 것이 좋습니다. 저희 웹 사이트에는 총 기록 수와 귀하가 현재 어떤 페이지에 있는지를 나열하는 영역이 있습니다.

이전에는 전체 레코드 세트를 가져 왔고이를 프로그래밍 방식으로 페이징 할 수있었습니다. 그러나 FETCH NEXT X ROWS ONLY와 함께 SQL 방식을 사용하면 X 행만 다시 제공되므로 총 레코드 세트가 무엇인지, 최소 및 최대 페이지를 계산하는 방법을 알 수 없습니다. 내가 이것을 알 수있는 유일한 방법은 함수를 두 번 호출하고 첫 번째 행 수를 수행 한 다음 FETCH NEXT로 두 번째 행을 실행하는 것입니다. 쿼리를 두 번 실행하지 않는 더 좋은 방법이 있습니까? 성능을 늦추는 것이 아니라 속도를 높이려고합니다.



답변

COUNT(*) OVER()… 를 사용할 수 있습니다 . 다음은 다음을 사용하는 간단한 예입니다 sys.all_objects.

DECLARE
  @PageSize INT = 10,
  @PageNum  INT = 1;

SELECT
  name, object_id,
  overall_count = COUNT(*) OVER()
FROM sys.all_objects
ORDER BY name
  OFFSET (@PageNum-1)*@PageSize ROWS
  FETCH NEXT @PageSize ROWS ONLY;

그러나 이것은 작은 데이터 세트를 위해 예약되어야합니다. 더 큰 세트에서는 성능이 좋지 않을 수 있습니다. 인덱싱 된 뷰 유지 (결과가 필터링되지 않았거나 절을 미리 알고있는 경우에만 작동 함 ) 및 트릭 사용을 포함한 더 나은 대안은이 Paul White 기사를 참조하십시오 .WHEREROW_NUMBER()


답변

COUNT (를 사용하여 몇 가지 성능 문제가 발생했습니다. ) OVER () 메서드를 . (10 개의 레코드를 반환하는 데 40 초가 걸리고 나중에 문제가 없었기 때문에 서버인지 확실하지 않습니다.)이 기술은 COUNT ( ) OVER () 를 사용하지 않고도 모든 조건에서 작동했으며 같은 것:

DECLARE
    @PageSize INT = 10,
    @PageNum  INT = 1;

WITH TempResult AS(
    SELECT ID, Name
    FROM Table
), TempCount AS (
    SELECT COUNT(*) AS MaxRows FROM TempResult
)
SELECT *
FROM TempResult, TempCount
ORDER BY TempResult.Name
    OFFSET (@PageNum-1)*@PageSize ROWS
    FETCH NEXT @PageSize ROWS ONLY


답변

James Moberg의 답변을 바탕으로 :

Row_Number()SQL Server 2012가없고 OFFSET을 사용할 수없는 경우을 사용하는 대안입니다.

DECLARE
    @PageNumEnd INT = 10,
    @PageNum  INT = 1;

WITH TempResult AS(
    SELECT ID, NAME
    FROM Tabla
), TempCount AS (
    SELECT COUNT(*) AS MaxRows FROM TempResult
)

select *
from
(
    SELECT
     ROW_NUMBER() OVER ( ORDER BY PolizaId DESC) AS 'NumeroRenglon',
     MaxRows,
     ID,
     Name
    FROM TempResult, TempCount

)resultados
WHERE   NumeroRenglon >= @PageNum
    AND NumeroRenglon <= @PageNumEnd
ORDER BY NumeroRenglon


답변