Open-Closed Principle

OFFSET-FETCH 사용법 본문

Programming/MS-SQL

OFFSET-FETCH 사용법

대박플머 2015. 4. 29. 00:35

웹에서 프로그래밍을 하다보면 게시판처럼 페이징을 해야 하는 경우가 있다. 

여기서 이야기 하는 페이징은 모든 데이터가 다 보이는 것이 아니라 정해진 크기만큼의 데이터 양을 순서대로 그룹을 형성하며 

보여지는 형태를 이야기 한다. 


정해진 크기의 데이터 만큼만 순서대로 보여줘야 하기 때문에 데이터 전체를 일렬로 나열을 해야 한다. 

나열되는 순서는 데이터가 들어온 순서도 될 수 있고 데이터가 저장된 순서라던지 다양한 순서가 있을 것이다. 

이렇게 데이터를 순서를 정한뒤 이 순서들중에서 필요한 데이터의 몇번째 그룹을 가져 올껀지 BETWEEN AND를 사용하여 가져오는게 일반적이다. 

잘 이해가 안간다면 여기서 간단하게 쿼리를 만들어 보겠다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
 
 
Create Table TestDB(
    Id INT identity 
  , Title VarChar(40Not Null
  , Content VarChar(Max) Not Null
)
 
Insert TestDB
(Title, Content)
Values('Title1''Content1'), ('Title2''Content2');
 
Declare @CurrentPage int
Declare @RowSize int
 
Set @CurrentPage = 1
Set @RowSize = 1
 
 
Select A.Title, A.Content
From (
    Select Row_Number() Over(Order by ID ASC) AS RowNum, 
        Title, 
        Content
    From TestDB
) A
Where (A.RowNum > (@CurrentPage - 1* @RowSize)
And (A.RowNum < (@CurrentPage * @RowSize) + 1)
cs

뭐 대충 짜면 이정로도 페이징을 할 수 있을 것이라고 생각이 된다. 

그렇기 때문에 기본적으로 Row_Number()를 통해서 정렬을 한 테이블을 서브쿼리로 사용하는 쿼리가 나오게 된다. 


그런데 오늘 소개 하려는 녀석을 보면 그런게 아무 짝에도 쓸모가 없다. 그냥 지가 알아서 필터링을 한다. 

그럼 간단하게 예제 쿼리를 작성해보도록 하자. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 
Create Table TestDB
(    
    Id INT identity   
  , Title VarChar(40Not Null  
  , Content VarChar(Max) Not Null
 
Insert TestDB(Title, Content)
Values('Title1''Content1')
    , ('Title2''Content2')
    , ('Title3''Content3')
    , ('Title4''Content4')
    , ('Title5''Content5')
    , ('Title6''Content6')
    , ('Title7''Content7')
    , ('Title8''Content8')
    , ('Title9''Content9')
    , ('Title10''Content10')
    , ('Title11''Content11')
    , ('Title12''Content12')
    , ('Title13''Content13'); 
 
Declare @CurrentPage int
Declare @RowSize int 
Set @CurrentPage = 1
Set @RowSize = 10
 
 
Select Title, Content
From TestDB
Order By Id
OFFSET (@CurrentPage -1* @RowSize FETCH NEXT @RowSize ROWS ONLY; 
 
 
cs


밑에 보면 OFFSET-FETCH를 사용한 것을 볼 수 있다. 

이 얼마나 쉬운 녀석인가 솔찍히 로우넘을 사용해서 BETWEEN을 사용한다거나 간단하게 연산을 하여 페이지을 하는 것보다 .

이게 가독성도 좋고 훨씬 수정도 편한다. 

OFFSET-FETCH 절은 건너뛸 수 있는 기능을 제공한다는 접에서 TOP보다 훨씬 유연하다. 

거기다가 OFFSET-FETCH는 표준 SQL의 기능이지만 페이징에서 주로 사용하는 TOP같은 경우는 그렇지 않기 때문에 OFFSET-FETCH를 사용하는 것을 권장한다. 


끝말.

프로그래밍을 하다보면 데이터를 불러올때 효과적으로 원하는 데이터를 가져올때 유용한 기능들이 많이 있는 것 같다.

아무 생각없이 Google형님에게 자바 페이징, asp 페이징 이런게 검색하면 뭐가 좋은지 뭐가 편한지 알수가 없다. 

알수 없는게 아니라 알려고 하지도 않는다. 우리 나라 개발자들은 (모두 그런건 아니겠지만) 가져다 써서 기능이 완성되면 좋아하니깐(특히 상사가)

쿼리를 작성하는 모든 개발자들은 성능에 예민할 것이다. 그리고 한번씩 DB가 락이 건란다거나 하면 더욱 뼈저리게 느끼고 있을 것이다. 

이거저거 많이 해보자 그리고 좋은거 찾자 MS형들은 잘 안가르쳐 주니깐 직접 찾는 수밖에 ㅋㅋㅋ


'Programming > MS-SQL' 카테고리의 다른 글

[MS-SQL]공통 테이블 식(CTE)  (0) 2016.02.12
[MS-SQL] DELETE JOIN  (0) 2016.02.04
[MS-SQL]데이터 삭제 DELETE vs TRUNCATE  (0) 2016.02.03
[MS-SQL]SELECT INTO 구문  (0) 2016.02.03
[MS-SQL]Identity 속성  (0) 2016.02.02