게시판 리스트 쿼리 질문 드립니다. 0 13 1,673

by Albothyl [2014.08.08 09:21:42]


실행계획.png (12,662Bytes)

아래 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 <=  (페이지번호) * (페이지에 보여줄 게시글 수)

 

by 비주류 [2014.08.08 09:33:18]

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페이지 건수만큼 조회할때는 인덱스만 적절하다면 큰 무리는 없을 것 같은데 상황봐서 판단가능할 것 같습니다.


by Albothyl [2014.08.08 10:10:19]

 subjectcode_2, 3은 제가 지금은 사용 안하는 변수입니다. 제외 해도 됩니다.

페이징 처리는 알려주신 쿼리를 적용해보겠습니다. !


by 마농 [2014.08.08 09:56:03]

1. 인덱스 힌트 사용 방법이 틀렸습니다.
   - 테이블명이 빠졌네요. (테이블명 인덱스명)
2. 인덱스의 구성이 올바른지 확인이 필요합니다.
   - (subjectcode_1, tradeno) 로 구성되어 있어야 합니다.
3. ROWNUM 조건을 안쪽에도 넣으면 범위를 줄일 수 있습니다.
   - AND ROWNUM <= (페이지번호) * (페이지에 보여줄 게시글 수)
4. 토탈 카운트를 함께 구하면 부분범위 처리를 할 수 없습니다.
   - 카운트는 별도로 구하세요
5. 함수 사용은 인라인뷰 밖 최종 Select절에서 사용하시면 됩니다.
   - 함수수행횟수 = 페이지에 보여줄 게시글 수


by Albothyl [2014.08.08 10:07:54]

2. 인덱스 구성을 확인하라고 하셨는데 subjectCode_1, tradeNo를 복합키로 구성하하는 애기 맞나요?

맞다면 이렇게 복합키로 구성했을 때 어떤 장점과 단점이 있나요?

4. 카운트는 별도로 구하라는것은 별로의 function으로 빼서 따로 구하는게 맞을까요?


by 마농 [2014.08.08 10:09:44]

토탈 카운트나, 댓글수는 함수로 만들어도 되지만...

굳이 함수를 사용할 이유는 없습니다.

최종 Select 절에서 스칼라서브쿼리를 이용하세요.


by Albothyl [2014.08.08 10:13:50]

아 최종에서 스칼라서브쿼리로 하면...20번밖에 반복하지 않으니 이 부분에서는 그렇게하는게 좋겠네요!


by 마농 [2014.08.08 10:15:13]

댓글 수를 구하기 위한 조건절에도 인덱스가 있어야겠죠.


by Albothyl [2014.08.08 10:20:29]

댓글 수를 구하기 위한 조건절에 인덱스를 넣으려면 해달 댓글 테이블의 키를 잡아줘야 할텐데

아래 와같이 해주면 되겠죠?

SELECT COUNT(*)
FROM    TBL_REPLY
WHERE REPLY_NO = REPLAY_NO

//정렬은 일단 생략

 


by 마농 [2014.08.08 10:23:41]

메인쿼리의 인라인뷰에 알리아스를 주고, (...) a

서브쿼리에서는 (SELECT COUNT(*) FROM tbl_reply WHERE reply_no = a.tradeno)

tbl_reply(reply_no) 인덱스 필요.

카운트 하는데 왠 정렬?


by Albothyl [2014.08.08 10:30:08]

아이고... 정렬이라니 정신이 없어서 실수했네요 ㅠ

답변 정말 감사합니다. !!


by 아발란체 [2014.08.08 10:20:46]

게시판 관련 보물같은 종결판 강과가 있습니다 ~ :)

http://www.gurubee.net/lecture/2287

 

 


by Albothyl [2014.08.08 10:21:18]

감사합니다 !!! ㅠㅠ


by Albothyl [2014.08.08 11:27:33]

답변 달아주신분들 정말 감사합니다. 덕분에 고민하던 문제들을 해결하였습니다. 감사합니다. !!

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입