테스트 사이트 - 개발 중인 베타 버전입니다

재귀호출 쿼리 좀 도와주세요 채택완료

고기조아 2년 전 조회 1,077

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

 

 

/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에 부하가 엄청 걸려서 락이 많이 걸리네요.

 

댓글 불러오는 부분

</p>

<p>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 <span style="color:#e74c3c;"><u><em><strong>getSubCommentList</strong></em></u></span>($comment_id, $write_table); ?>

                </li>

                <?php

            }

            ?></p>

<p>

 

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

</p>

<p>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."
";

                $result = sql_query($sql);</p>

<p>                $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>';

                }</p>

<p>                return $strHtml;

           }</p>

<p>

댓글을 작성하려면 로그인이 필요합니다.

답변 2개

2년 전

재귀호출은 아닙니다.

 

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

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

 

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

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

</p>

<p>sql_free_result($result)</p>

<p>

 

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

 

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

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

 

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

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

로그인 후 평가할 수 있습니다

댓글을 작성하려면 로그인이 필요합니다.

인덱스를 살펴 보면

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을 추가해 보세요.

로그인 후 평가할 수 있습니다

댓글을 작성하려면 로그인이 필요합니다.

답변을 작성하려면 로그인이 필요합니다.

로그인