생활
php에서 반복되는 sql 쿼리를 어떻게 하면 하나로 끝낼 수 있을까요?
안녕하세요.
php, mysql을 사용한 그누보드 서버에서 아래와 유사한 코드를 사용중인데요, 이렇게 하면 mysql이 cpu를 다 잡아먹어서 과부하가 걸립니다.
해결방법을 찾다가 sql문을 루프돌리는것보다는 join으로 해결하라고 하는 글을 봤는데 실제로 sql문을 과도하게 실행하는게 서버 부하의 주원인입니다.
그래서 sql쿼리를 한번만 사용하도록 코드를 바꾸고 싶은데 sql에 대해 많이 미숙해서 어떻게 바꿔야할지 잘 모르겠어서 도움 부탁드립니다.
코드를 설명드리자면, 테이블의 24시간치 데이터를 가지고 100 / 분당 레코드수를 계산한 값을 모두 합하는 코드입니다.
혹시 이해하기 어려우실까봐 2분 데이터만 사용하는걸로 예를들면 처음 1분은 100개의 레코드가 있고, 다음 1분은 50개의 데이터가 있다고 하면
$sum = 100/100 + 100/50 즉, 3이 나옵니다.
2분이면 루프가 2번이지만, 아래 코드는 24시간 데이터니까 24*60 = 1440번 루프를 실행하게 되죠.
sql_fetch가 그누보드 함수던데 혹시라도 그누보드를 안쓰시는 전문가님들이 계실수도 있어서 아래에 해당함수 내용을 추가했습니다.
문제의 코드:
$sum = 0; for ($i = 0; $i < 1440; $i++){ // 24시간 * 60분 = 1440 $time1 = date("Y/m/d H:i",(strtotime($basetime) - 864000 + ($i * 60))).":00"; // $basetime으로부터 24시간 전부터 1분전까지 1분씩 증가 $time2 = date("Y/m/d H:i",(strtotime($basetime) - 60 + ($i * 60))).":59"; // $basetime으로부터 23:59:59 전부터 basetime까지 1분씩 증가 $sql = "select count(*) as cnt from mytable where start_time between '$time1' and '$time2'"; // mytable에서 $time1~$time2 시간 사이(1분)의 레코드수를 가져오는 쿼리 $query_result = sql_fetch($sql); // 쿼리 실행 $sum += 100 / $query_result['cnt']); // 100/레코드수를 누적합산 } echo $sum;sql_fetch 함수:
function sql_fetch($sql, $error=TRUE) { $result = sql_query($sql, $error); //$row = @sql_fetch_array($result) or die("<p>$sql<p>" . mysql_errno() . " : " . mysql_error() . "<p>error file : $_SERVER[PHP_SELF]"); $row = sql_fetch_array($result); return $row; } function sql_fetch_array($result) { $row = @mysql_fetch_assoc($result); return $row; }55글자 더 채워주세요.
1개의 답변이 있어요!
- 우선 자료는 이렇게 준비했습니다 --------- | 2020-10-30 01:04:13 | | 2020-10-30 08:33:04 | | 2020-10-30 08:47:13 | | 2020-10-30 09:45:02 | | 2020-10-30 09:48:35 | | 2020-10-30 10:02:09 | | 2020-10-30 10:37:44 | | 2020-10-30 10:38:54 | | 2020-10-30 10:43:53 | | 2020-10-30 10:44:46 | | 2020-10-30 10:47:51 | | 2020-10-30 10:57:21 | | 2020-10-30 11:21:21 | | 2020-10-30 11:26:46 | | 2020-10-30 11:41:36 | | 2020-10-30 11:45:26 | | 2020-10-30 12:43:35 | --------- 질의문은 아래와 같으며 결과물은 시간별 총 몇개의 레코드 갯수가 있는지 나옵니다 MariaDB [pay2id]> select wr_datetime , date_format(wr_datetime,"%H") as dd , count(*) as cnt from g5_write_free where wr_datetime between date('2020-10-30') and date('2020-10-30')+1 group by dd order by dd asc; +---------------------+------+-----+ | wr_datetime | dd | cnt | +---------------------+------+-----+ | 2020-10-30 01:04:13 | 01 | 1 | | 2020-10-30 08:33:04 | 08 | 2 | | 2020-10-30 09:45:02 | 09 | 2 | | 2020-10-30 10:02:09 | 10 | 7 | | 2020-10-30 11:21:21 | 11 | 4 | | 2020-10-30 12:43:35 | 12 | 1 | +---------------------+------+-----+
위 질의문을 이용하여 sql 명령중 fetch 를 이용하여 while 로 돌리면
원하시는 결과를 얻으실 수 있을것입니다.