일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 15552
- 저장
- PARTITION BY
- 별찍기
- 집합 연산자
- 예제
- for문
- 트리거
- 연결
- join
- rank
- sql 예제
- 프로시저
- java
- 조건문
- 그룹함수
- Sequence
- 데이터베이스
- union
- BufferedReader
- 단일행 함수
- 무결성 제약 조건
- 반복문
- 오라클
- 이클립스
- 백준
- 서브쿼리
- while
- SQL
- BufferedWriter
- Today
- Total
control Y
[오라클] 데이터베이스 페이징 처리[ORDER BY, INDEX] 본문
데이터베이스를 이용할 때 웹이나 앱에서 가장 신경 쓰는 부분
- 빠르게 처리
- 필요한 양만큼만 데이터를 가져오는 것
ORDER BY 문제점
빠르게 동작하는 SQL을 위해서는 가능한 ORDER BY를 사용하지 말아야 함.
ORDER BY는 데이터가 많은 경우 엄청난 성능 저하를 가져 오기 때문에 order by는 주의해야한다.
INDEX 사용하는 이유
인덱스라는 존재가 이미 정렬된 구조이므로 이를 이용해서 별도의 정렬을 하지 않기 때문에
데이터가 많은 경우 ORDER BY 대신 사용한다.
SELECT /* + INDEX_DESC(spring_board spring_board_pd) */
*
from spring_board where b_num > 0;
인덱스와 오라클 힌트
- 오라클은 select문을 전달할 때 hint라는 것을 사용할 수 있음.
- 힌트는 개발자가 데이터베이스에 어떤 방식으로 실행해 줘야하는지 명시하여 조금의 강제성이 부여됨.
- select문을 작성 할 때 힌트는 잘못 작성되어도 실행 할 때는 무시되기만 하고 별도의 에러는 발생하지 않음.
[ 예시 구문 ]
/* +로 시작하고 */ 로 끝남
FULL(테이블명): /* + FULL(spring_board */
INDEX_ASC, INDEX_DESC: /* + INDEX_DESC(spring_board spring_board_pk) */
rownum과 인라인 뷰
- 전체가 아닌 필요한 만큼의 데이터를 가져오는 방식
- rownum이라는 키워드를 사용해서 데이터에 순번을 붙여 사용한다
select rownum, b_num,b_num, b_title, to_char(b_date,'YYYY-MM-DD') AS B_DATE
FROM spring_board;
한페이지당 10개의 데이터 출력
select /*+ INDEX_DESC(spring_board spring_board_pk) */
rownum, b_num, b_name, b_title, to_char(b_date,'YYYY-MM-DD') as b_date
FROM spring_board where rownum <= 10;
두번째 페이지 데이터를 구하기 위해 11번부터 20번까지의 데이터를 출력하도록 코딩할 경우
SELECT /*+ INDEX_DESC(spring_board spring_board_pk) */
rownum, b_num, b_name, b_title, to_char(b_date,'YYYY-MM-DD') as b_date
FROM spring_board where rownum > 10 and rownum <=20;
> 아무 데이터도 출력하지 않는다
> rownum의 조건은 반드시 1이 포함되어야 하기 때문이다
20번까지 출력 > 1이 포함되어 있기 때문에 출력 가능
SELECT /*+ INDEX_DESC(spring_board spring_board_pk) */
rownum, b_num, b_name, b_title, to_char(b_date,'YYYY-MM-DD') as b_date
FROM spring_board where rownum <=20;
10에서 20을 출력하기 위해서 인라인 뷰 처리를 한다.
SELECT rnum, b_num, b_name, b_title, to_char(b_date, 'YYYY-MM-DD') as b_date
from(
SELECT /*+ INDEX_DESC(spring_board spring_board_pk) */
rownum as rnum, b_num, b_name, b_title, b_date
FROM spring_board
where rownum <= 20
)boardlist
where rnum > 10;
이 과정을 정리하면 다음과 같은 순서이다.
- 필요한 순서로 정렬된 데이터에 ROWNUM을 붙인다
- 처음부터 해당 페이지의 데이터를 ROWNUM<=20과 같은 조건을 이용해서 구한다.
- 구해놓은 데이터를 하나의 테이블처럼 간주하고 인라인뷰로 처리한다.
- 인라인뷰에서 필요한 데이터만을 남긴다
페이징 처리
페이징 처리를 위해서 필요한 파라미터
- 페이지 번호
- 한페이지당 몇 개의 데이터를 보여줄 것인지 결정
화면에 페이징 처리
화면에 페이징 처리를 하기 위해서는 우선적으로 여러가지 필요한 정보들이 존재한다.
- 현재 페이지 번호
- 이전과 다음으로 이동 가능한 링크의 표시 여부(prev, next)
- 화면에서 보여지는 페이지의 시작번호와 끝번호(startPage, endPage)
끝 페이지 번호와 시작 페이지 번호
페이징 처리를 하기 위해서 우선적으로 필요한 정보는 현재 사용자가 보고있는 페이지의 정보이다 보통 바로가기 페이지 번호를 1페이지 부터 10 페이지로 한다면 5페이지를 본다면 화면의 페이지번호는 1페이지부터 시작해야 하고 만일 15페이지를 본다면 11페이지부터 시작해야한다.
페이징의 끝번호 계산 |
this.endPage = (int) (Math.ceil(cvo.getPageNum() / 10.0)) * 10; |
Math.ceil() 메서드는 소수점을 올림으로 처리하기 때문에 다음과 같은 상황이 가능
- 1페이지의 경우 : Math.ceil(0.1) * 10 = 10
- 2페이지의 경우 : Math.ceil(0.2) * 10 = 10
- 10페이지의 경우 : Math.ceil(1) * 10 = 10
- 11페이지의 경우 : Math.ceil(1.1) * 10 = 20
- 20페이지의 경우 : Math.ceil(2) * 10 = 20
이 때 전체 데이터 수가 적다면 10페이지로 끝나면 안되는 상황이 생길 수도 있기에 아직은 개선이 더 필요하다.
그리고 화면에 10개씩 보여준다면 시작번호는 무조건 끝번호에서 9를 빼주면 된다.
페이징의 시작번호 계산 |
this.startPage = this.endPage-9; |
끝번호는 전체 데이터수에 의해서 영향을 받는다
전체 데이터수를 통한 끝번호 재계산 |
int realEnd = (int)(Math.ceil(total*1.0) / cvo.getAmount())); if(realEnd <= this.endPage) { this.endPage = realEnd; } |
이전(prev) 구하기(시작번호가 1보다 큰 경우 존재)
this.prev = this.startPage > 1;
다음(next) 구하기(realEnd가 끝 번호보다 큰 경우 존재)
this.next = this.endPage < realEnd;
'KH정보교육원 > SQL' 카테고리의 다른 글
PL/SQL 예외 (0) | 2023.06.30 |
---|---|
[오라클/자바] 이클립스(eclipse) 데이터 베이스 연동 (0) | 2023.06.27 |
[오라클] 저장 · 프로시저 · 트리거 함수[작성중] (0) | 2023.06.27 |
[오라클] JDBC (0) | 2023.06.26 |
[오라클]PL/SQL (0) | 2023.06.26 |