푸른청년 푸르게 살고있나?  
home | 살아가기 | news | 세상보기 | tip&tech | 방명록 |  
   전체
   asp
   php
   jsp
   mssql
   mysql
   informix
   linux
   unix
   win2000
   javascript
   html
   oracle
   java
   etc
    
:: Tip&Tech > php
[php+mysql]백만건 게시판 만들기
php  스쿨에  올라왔던  내용입니다.
아래의 알고리즘에 따라 제가 만들어본 테스트 사이트입니다.
http://222.112.187.32:9090:8080/blueboard/list.php?tbn=test

테스트 데이터를 넣는데 10만건 한번에 넣으니까 내 컴퓨터가 다운 되는군여..
5만건씩 넣다보니까 시간이 마니 걸려서.. 아직 데이터가 백만건 안됩니다만 시간나는대로 백만건 넣고 테스트해보져.


UID : 자동증가필드
PID : 정렬필드(인덱스)
THREAD : 응답글의 깊이

최초 등록글은
UID : 1
PID : 9999999.0000
THREAD : 0
이 됩니다.

두번째 등록글은
UID : 2
PID : 9999998.0000
THREAD : 0

첫번째 등록글에 답변글을 달면
UID : 3
PID : 9999999.0001
THREAD : 1
이 됩니다.

첫번째 등록글의 답변글에 답변을 달면
UID : 4
PID : 9999999.0002
THREAD : 2
가 됩니다..
원본글의 PID 에 0.0001 을 더해주고
원본글의 THREAD 에 1 을 더해줍니다.

첫번째 등록글의 첫번째답변글에 답변을 달면
UID : 5
PID : 9999999.0002
THREAD : 2
가 되고 이때, 답변글의 PID 를 업데이트 합니다..
PID
-----------
9999999.0000
9999999.0001
9999999.0002

에서 9999999.0001 에 답변을 달면
그 답변글의 PID 는 + 0.0001 을 통해 9999999.0002 로 등록해 주고
이미 있었던 9999999.0002 는 + 0.0001 을 통해 9999999.0003 으로 업데이트해 줍니다..

일반적인 업데이트 게시판에서 10만개의 게시물이 있을때 1번글에 답변을 달면 99999개의 게시물을 업데이트해야 하므로 글등록속도가 상당히 느려지는데요..

위와 같은 경우 10만개는 물론 100만개일찌라도 전체를 업데이트하지 않고
PID 중 소수점이상이 같은 게시물에 대해서만 업데이트를 하므로 글등록에 따른 속도저하가 없습니다.

일반글 등록시는

$PID_NUM = mysql_fetch_array(mysql_query("SELECT min(PID) FROM $table", $DB_CONNECT));
if($PID_NUM[0]) {$PID = $PID_NUM[0] - 1;} else {$PID = 9999999.0000;}

답변글 등록시는

$REPLY_DATA = mysql_fetch_array(mysql_query("SELECT * FROM $table WHERE UID='$원본글의UID값'",$DB_CONNECT));
if($REPLY_DATA[PID]) {
$PID = $REPLY_DATA[PID] + 0.0001;
$DPID = $REPLY_DATA[PID];
$UPID = intval($PID)+1;
$THREAD = $REPLY_DATA[THREAD] + 1;

mysql_query("UPDATE myplus_$table SET PID=PID+0.0001 WHERE PID > $DPID AND PID < $UPID",$DB_CONNECT) or die(mysql_error());

본알고리즘은 소수점을 이용하면서 답변글만 업데이트하는 방식이구요..
기본이 ASC 정렬이므로 속도에 있어서도 개선이 있습니다..

문제가 있다면 9999999개를 넘어서는 원본글이 등록되는 경우와
하나의 원본글에 답변글이 9999개 이상이 달리는 경우입니다..
이 두문제는 거의 희박하겠지요..


하지만 위의 알고리즘으로만 하다보면 문제점이 있습니다.
첨 페이지들은 무쟈게 속도가 나오지만 뒤로 갈수록 속도 저하가 상당하져..
10만건까지는 마지막페이지가 1초정도 나오지만..
15만건 정도 되니까.. 60초까지 나오는 군여..
이상의 방법이 첫리스트를 뽑아오는데는 최상의 속도를 낼 수 있지만

반업데이트형 알고리즘의 취약점인 뒤쪽으로 갈 수록 페이징이 급격히 느려지는 현상 즉 절대로 LIMIT 100000,20 과 같은 LIMIT 으로는 뒷페이지에서 속도를 낼 수 없습니다.

그래서 where절에 PID의 시작포인트로 걸러주는게 필요합니다.

$RECNUM = 15; //한페이지당 출력수
$START_NUM = ($p-1)*$RECNUM; // 페이지분할시작점
$TEMP_DATA = mysql_fetch_array(mysql_query("SELECT PID
FROM $table ORDER BY PID LIMIT $START_NUM,1", $DB_CONNECT));
// INDEX가 걸린 PID를 정렬시켜 레코드 하나만 불러옵니다.
$S_PID = $TEMP_DATA[PID]-0.0001; //시작포인트에서 0.0001을 빼줍니다.
if(!$START_NUM) $S_PID = intval($S_PID)-1; //첫번째페이지라면 1을 빼줍니다.
// 이상을 통해 $S_PID, 즉 PID 의 시작포인트를 알아냈습니다.

$TABLE_DATA = mysql_query("SELECT * FROM $table WHERE PID > $S_PID ORDER BY $sort $orderby LIMIT 0,$RECNUM", $DB_CONNECT);
// PID 시작포인트보다 PID 가 큰글을 LIMIT 0,$RECNUM 을 통해 $RECNUM만큼만 뽑아옵니다..
// 이때, 항상 LIMIT 0,$RECNUM 을 이용하므로 속도가 저하되지 않습니다.
// 문제는 $S_PID 를 구할때 인덱스가 걸려있다고 해도 LIMIT 1000000,1 을
// 사용하므로 속도가 떨어지는데.. 이 수치는 게시물 100만건일때 마지막페이지를
// 불러오는 속도가 대략 0.7~1 초 정도되는군요..
// 100만건에서 마지막 페이지가 1초이내이면 그런대로 만족할만한 수치입니다.
// 물론 손을 더 보아야 할 것 같습니다...


날짜: 2003-10-16 17:39:42, 조회수: 5964

다음글 re:[php+mysql]백만건 게시판 만들기
이전글 [PHP]클래스 만들어 쓰기

꼬리말
글쓴이 비밀번호 #스팸글방지(주인장 닉네임을 쓰시오)

  
since by 2003.03.23 / 3th 2005.07.26 / 4th 2009.04.22 made by bluesoul