아래 SQL코드는 제가 작성한 게시판 리스트를 뽑는 쿼리입니다.
그런데 이 쿼리에는 한가지 문제점이 있습니다. 바로 " TABLE ACCESS FULL " 입니다.
처음에는 문제가 없겠지만 게시판의 글이 많으면 많아질수록 게시글의 리스트를 가져오는데
시간이 계속 증가한텐데... 아래 쿼리를 어떻게 고쳐야만 이 문제를 해결할 수 있을까요?
또 향후에 리플기능을 추가하면 게시글 리스트를 가져올 때 게시글당 달려있는 리플수를 가져
오는 function을 만들고 이를 SELECT에 추가하려고하는데, 그러면 게시글마다 함수를를 호출할
텐데 다른 좋은 방법이 있을까요?
** 파일첨부로 실행계획 캡쳐이미지를 올립니다.
=============================================================
SELECT /*+INDEX_DESC(SHTBOARD_PK_TRADENO)*/ tradeNo , subjectCode_1 , tradeStatus , title , content , totalCnt FROM( SELECT /*+INDEX_DESC(SHTBOARD_PK_TRADENO)*/ TRADENO tradeNo , SUBJECTCODE_1 subjectCode_1 , TRADESTATUS tradeStatus , TITLE title , CONTENT content , COUNT(*)OVER() totalCnt , ROWNUM RN FROM SHTBOARD WHERE SUBJECTCODE_1 = (게시판 카테고리코드) ) WHERE RN > ((페이지번호) - 1) * (페이지에 보여줄 게시글 수) AND RN <= (페이지번호) * (페이지에 보여줄 게시글 수)
1. 우선 인라인 뷰에서 전체 건수 COUNT(*) 를 빼시고, 힌트를 아래와 같이 변경하고 테스트 해보세요. 총 건수는 어떻게든 요건에서 빼시는 것이 좋겠습니다. (페이지 번호를 표시하는 대신, 다음 페이지 보기로 대체, 아니면 한번에 가져오는 건수를 어느정도 늘리되 거기까지만 페이지 번호를 표시 한다든지) 그런데 아래 predicate 쪽에나오는 subjectcode_1, 2, 3 은 뭔지 모르겠네요?
/*+ INDEX_DESC(SHTBOARD (인덱스컬럼,...)) */
2. 모든 경우에 맞지는 않겠지만 페이징 처리시에 보통 최근의 글을 많이 보니까 아래와 같이 처리 합니다.
SELECT * FROM ( SELECT ROWNUM RN, A.* FROM (SELECT /*+ INDEX_DESC(~) */ ~ FROM ~ WHERE ~ ORDER BY ~) A WHERE ROWNUM <= 페이지끝순번) ) WHERE RN > 페이지시작순번
3. 댓글 건수는 속도가 문제라면 변경시마다 테이블에 별도 컬럼으로 관리하시거나, 어차피 1페이지 건수만큼 조회할때는 인덱스만 적절하다면 큰 무리는 없을 것 같은데 상황봐서 판단가능할 것 같습니다.
1. 인덱스 힌트 사용 방법이 틀렸습니다.
- 테이블명이 빠졌네요. (테이블명 인덱스명)
2. 인덱스의 구성이 올바른지 확인이 필요합니다.
- (subjectcode_1, tradeno) 로 구성되어 있어야 합니다.
3. ROWNUM 조건을 안쪽에도 넣으면 범위를 줄일 수 있습니다.
- AND ROWNUM <= (페이지번호) * (페이지에 보여줄 게시글 수)
4. 토탈 카운트를 함께 구하면 부분범위 처리를 할 수 없습니다.
- 카운트는 별도로 구하세요
5. 함수 사용은 인라인뷰 밖 최종 Select절에서 사용하시면 됩니다.
- 함수수행횟수 = 페이지에 보여줄 게시글 수