순수 SQL에서 LINQ의 .Skip (1000) .Take (100)를 어떻게 작성합니까?


93

.Skip()LINQ 의 메서드에 해당하는 SQL은 무엇입니까 ?

예 : 특정 데이터베이스 테이블에서 1000-1100 행을 선택하고 싶습니다.

SQL만으로 가능합니까? 아니면 전체 테이블을 선택한 다음 메모리에서 행을 찾아야합니까? 테이블이 상당히 클 수 있으므로 가능하면 이것을 피하는 것이 이상적입니다.

답변:


78

SQL Server 2005 이상에서는 ROW_NUMBER 함수를 사용할 수 있습니다 . 예.

USE AdventureWorks;
GO
WITH OrderedOrders AS
(
    SELECT SalesOrderID, OrderDate,
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
    FROM Sales.SalesOrderHeader 
) 
SELECT * 
FROM OrderedOrders 
WHERE RowNumber BETWEEN 51 AND 60; --BETWEEN is inclusive

좀 더 자세한 내용은 내 대답의 링크를 참조하십시오. stackoverflow.com/questions/1744802/…
Mike Atlas

BETWEEN 51과 60-포괄적입니다.
Drew Miller

1
그러나 이것은 먼저 모든 것을 선택하고 그 선택에서 10 개만 가져갈 것입니다. 맞습니까? 아니면 첫 번째 쿼리 / 뷰에 이미 10 개만 있습니까?
Tadej

138

SQL Server 2012 이상에는 다음 구문이 추가되었습니다.

SELECT *
FROM Sales.SalesOrderHeader 
ORDER BY OrderDate
OFFSET (@Skip) ROWS FETCH NEXT (@Take) ROWS ONLY

11
OFFSET 명령을 사용하려면 ORDER BY ___를 사용해야합니다 .... 주문없이 페이지 매김을 시도해서는 안됩니다.
James Haug

또한 'new'구문은 이상하게도 @skip! row_number 접근 방식에는이 기능이 없습니다 (인덱싱 된 순서로만 테스트 됨). lo @Skip이 20 미만인 경우 새 구문은 row_number 접근 방식보다 빠릅니다.
Eske Rahn

22

LINQ to SQL은 ROW_NUMBER 윈도우 함수를 사용하여이 작업을 수행합니다.

  SELECT a,b,c FROM 
   (SELECT a,b,c, ROW_NUMBER() OVER (ORDER BY ...) as row_number
    FROM Table) t0
   WHERE to.row_number BETWEEN 1000 and 1100;

이 작품,하지만 ORDER BY에서 ROW_NUMBER을 제조 할 필요가 있습니다 쿼리 결과는 서버 측과 원인 성능 문제에 분류된다. 인덱스가 ORDER BY 요구 사항을 충족 할 수있는 경우에도 쿼리는 결과 반환을 시작하기 전에 1000 개의 행을 계산해야합니다. 너무 자주 개발자는 이것을 잊어 버리고 5mil 행 테이블에 페이지 매김 제어를 던지고 첫 페이지가 마지막 페이지보다 훨씬 빨리 반환되는 이유를 궁금해합니다.

그럼에도 불구하고 ROW_NUMBER ()를 사용하는 것은 정렬을 피할 경우 사용의 용이성과 좋은 성능 사이의 최상의 균형 일 것입니다 (ORDER BY 조건은 인덱스로 충족 될 수 있음).


1
추가 성능 정보를 제공해 주셔서 감사합니다.주의해서 테스트해야합니다.
Ray

테스트를 거쳐 50 만 행 테이블의 경우 마지막 페이지가 첫 페이지보다 약 7 배 느립니다. 이상적이지는 않지만 나에게는 허용됩니다.
Ray

6

이거 한번 해봐:

select * from [Table-Name] order by [Column-Name] 
offset [Skip-Count] rows
FETCH NEXT [Take-Count] rows only

예:

select * from Personals order by Id
offset 10 rows            --------->Skip 10
FETCH NEXT 15 rows only   --------->Take 15

4

이 작업을 수행:

LINQ to SQL 데이터 컨텍스트에서 .Skip (1000) .Take (100)를 실행하고 SQL 출력을 확인합니다. 설명하는 것을 수행하는 SQL 문을 생성합니다.

우아하지는 않지만 작업이 완료됩니다.


2
요청받은 것이 아닙니다.
RayLoveless

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.