재귀호출 쿼리 좀 도와주세요

재귀호출 쿼리 좀 도와주세요

QA

재귀호출 쿼리 좀 도와주세요

본문

게시판 댓글 시스템 커스텀 테스트중입니다.

 

 

/bbs/view.comment.php 에서 댓글 불러오는 쿼리가 실행중이고,(1번 쿼리)

$sql = " select * from $write_table where wr_parent = '$wr_id' and wr_is_comment = 1 order by $orderby ";

 

/skin/board/basic/view_comment.skin.php 에서 대댓글을 불러오는 쿼리를 삽입했습니다. (2번 쿼리)

$sql2 = "SELECT * FROM {$table_nm} WHERE wr_parent = $comment_id AND wr_is_comment = 1 ORDER BY wr_id";

 

1번 쿼리가 실행중에 2번 쿼리가 재귀호출되니 DB에 부하가 엄청 걸려서 락이 많이 걸리네요.

 

댓글 불러오는 부분


for ($i=0; $i<$cmt_amt; $i++) {
                $comment_id = $list[$i]['wr_id'];
                $cmt_depth = strlen($list[$i]['wr_comment_reply']) * 50;
                $comment = $list[$i]['content'];
                /*
                if (strstr($list[$i]['wr_option'], "secret")) {
                $str = $str;
                }
                */
                $comment = preg_replace("/\[\<a\s.*href\=\"(http|https|ftp|mms)\:\/\/([^[:space:]]+)\.(mp3|wma|wmv|asf|asx|mpg|mpeg)\".*\<\/a\>\]/i", "<script>doc_write(obj_movie('$1://$2.$3'));</script>", $comment);
                $cmt_sv = $cmt_amt - $i + 1; // 댓글 헤더 z-index 재설정 ie8 이하 사이드뷰 겹침 문제 해결
                $c_reply_href = $comment_common_url.'&c_id='.$comment_id.'&w=c#bo_vc_w';
                $c_edit_href = $comment_common_url.'&c_id='.$comment_id.'&w=cu#bo_vc_w';
                $is_comment_reply_edit = ($list[$i]['is_reply'] || $list[$i]['is_edit'] || $list[$i]['is_del']) ? 1 : 0;
                ?>
                <li>
                    <div class="info">
                        <span><?php echo $list[$i]['wr_name'] ?></span>
                        <div class="date">
                            <i><?php echo $list[$i]['datetime'] ?></i>
                        </div>
                        <div class="modify">
                            <?php if ($user['mb_id'] == $list[$i]['mb_id']) { ?>
                            <button type="button" class="btn_edit" data-key="<?php echo $comment_id ?>"><span class="blind">수정</span></button>
                            <button type="button" class="btn_remove" data-key="<?php echo $comment_id ?>"><span class="blind">삭제</span></button>
                            <?php } ?>
                        </div>
                        <div class="util">
                            <button type="button" class="btn_c_report" data-key="<?php echo $comment_id ?>">신고 <?php echo number_format($list[$i]['wr_nogood']) ?></button>
                            <button type="button" class="btn_reply" data-key="<?php echo $comment_id ?>">답글</button>
                            <button type="button" class="btn_reply_cancel" data-key="<?php echo $comment_id ?>">취소</button>
                        </div>
                    </div>
                    <div class="cmnt_cont" id="cmnt_cont_<?php echo $comment_id ?>">
                        <div class="cmnt_text" id="cmnt_text_<?php echo $comment_id ?>" style="white-space: pre-line">
                            <p><?php echo $comment ?></p>
                        </div>
                        <div class="cmnt_input" id="cmnt_input_<?php echo $comment_id ?>">
                            <textarea id="cmnt_content_<?php echo $comment_id ?>"><?php echo $comment ?></textarea>
                            <button type="button" id="btnCmntEdit" data-id="<?php echo $comment_id ?>">수정</button>
                        </div>
                    </div>
                    <div class="cmnt_reply_wr" id="cmnt_reply_wr_<?php echo $comment_id ?>">
                        <div class="cmnt_input">
                            <textarea id="cmnt_reply_content_<?php echo $comment_id ?>"></textarea>
                            <button type="button" id="btnAddCmntReply" data-id="<?php echo $comment_id ?>">등록</button>
                        </div>
                    </div>
                    <?php echo getSubCommentList($comment_id, $write_table); ?>
                </li>
                <?php
            }
            ?>

 

위 구문에서 호출하는 함수 부분


function getSubCommentList($comment_id, $table_nm) {
                $sql = "SELECT * FROM {$table_nm} WHERE wr_parent = '$comment_id' AND wr_is_comment = '1' ORDER BY wr_id";
                //$sql = "SELECT wr_name, wr_datetime, mb_id, wr_nogood, wr_content, wr_comment_reply FROM {$table_nm} WHERE wr_is_comment = '1' AND wr_parent = '$comment_id' ORDER BY wr_id";
//                echo $sql."<br>";
                $result = sql_query($sql);
                $strHtml = '';
                if (sql_num_rows($result) > 0) {
                    $strHtml = '<ul class="reply_list">';
                    for ($i=0;$row=sql_fetch_array($result);$i++) {
                        $strHtml .= '
                                <li>
                                    <div class="info">
                                        <span>'.$row['wr_name'].'</span>
                                        <div class="date">
                                            <i>'.date('Y-m-d', strtotime($row['wr_datetime'])).'</i>
                                            <i>'.date('H:i:s', strtotime($row['wr_datetime'])).'</i>
                                        </div>
                                        <div class="modify">';
                        if ($user['mb_id'] == $row['mb_id']) {
                            $strHtml .= '   <button type="button" class="btn_edit" data-key="' . $row['wr_id'] . '"><span class="blind">수정</span></button>
                                            <button type="button" class="btn_remove" data-key="' . $row['wr_id'] . '"><span class="blind">삭제</span></button>';
                        }
                        $strHtml .= '   </div>
                                        <div class="util">
                                            <button type="button" class="btn_c_report" data-key="'.$row['wr_id'].'">신고 '.number_format($row['wr_nogood']).'</button>
                                            <button type="button" class="btn_reply" data-key="'.$row['wr_id'].'">답글</button>
                                            <button type="button" class="btn_reply_cancel" data-key="'.$row['wr_id'].'">취소</button>
                                        </div>
                                    </div>
                                    <div class="cmnt_cont" id="cmnt_cont_'.$row['wr_id'].'">
                                        <div class="cmnt_text" id="cmnt_text_'.$row['wr_id'].'">
                                            <p>'.$row['wr_content'].'</p>
                                        </div>
                                        <div class="cmnt_input" id="cmnt_cont_'.$row['wr_id'].'">
                                            <textarea id="cmnt_content_'.$row['wr_id'].'">'.$row['wr_content'].'</textarea>
                                            <button type="button" id="btnCmntEdit" data-id="'.$row['wr_id'].'">수정</button>
                                        </div>
                                    </div>
                                    <div class="cmnt_reply_wr" id="cmnt_reply_wr_'.$row['wr_id'].'">
                                        <div class="cmnt_input" id="cmnt_input_'.$row['wr_id'].'">
                                            <textarea id="cmnt_reply_content_'.$row['wr_id'].'"></textarea>
                                            <button type="button" id="btnAddCmntReply" data-id="'.$row['wr_id'].'">등록</button>
                                        </div>
                                    </div>';
                        $strHtml .= getSubCommentList($row['wr_id'], $table_nm);
                        $strHtml .= '    </li>';
                    }
                    $strHtml .= '</ul>';
                }
                return $strHtml;
           }

이 질문에 댓글 쓰기 :

답변 2

인덱스를 살펴 보면

show index from g5_write_free ;
+------------------+------------+---------------------+--------------+---------------+
| Table            | Non_unique | Key_name            | Seq_in_index | Column_name   |
+------------------+------------+---------------------+--------------+---------------+
| g5575_write_free |          0 | PRIMARY             |            1 | wr_id         |
| g5575_write_free |          1 | wr_seo_title        |            1 | wr_seo_title  |
| g5575_write_free |          1 | wr_num_reply_parent |            1 | wr_num        |
| g5575_write_free |          1 | wr_num_reply_parent |            2 | wr_reply      |
| g5575_write_free |          1 | wr_num_reply_parent |            3 | wr_parent     |
| g5575_write_free |          1 | wr_is_comment       |            1 | wr_is_comment |
| g5575_write_free |          1 | wr_is_comment       |            2 | wr_id         |
+------------------+------------+---------------------+--------------+---------------+

7 rows in set (0.00 sec)

 

wr_parent와 wr_is_comment 조합은 인덱스 사용을 안 하것으로 보입니다.

wr_num을 추가해 보세요.

재귀호출은 아닙니다.

 

쿼리1은 이미 실행 종료된 상태이고

skin 쪽에서의 반복문은 쿼리2만 반복 실행합니다.

 

쿼리1 의 할당 리소스를 먼저 해제하고 싶다면

skin 쪽에서 가장 윗 라인에 다음처럼 시도해 볼수 있습니다.


sql_free_result($result)

 

다만 현재 DB 부하에 직접적인 큰 연관성은 없을것 같습니다.

 

쿼리1, 쿼리2 모두 Limit 절. 페이징이 없습니다.

각 쿼리의 result rows 가 과도하게 나오는 경우라면 페이징이 필요한 상황일수 있습니다.

 

추가적으로 적절한 솔루션이 될지는 모르겠지만

INNER JOIN 을 이용한 한번의 쿼리로 가져오는 방법도 있을것 같습니다.

답변을 작성하시기 전에 로그인 해주세요.
전체 123
QA 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT