개발 Q&A

제목 주기적으로 쿼리 해주는걸 어떻게 하나요
글쓴이 jake 작성시각 2012/03/08 16:24:52
댓글 : 8 추천 : 0 스크랩 : 0 조회수 : 27618   RSS
안녕하세요

실시간 검색 리스트를 만들고 있는데

매번 쿼리를 돌려서 보여주는게 서버에 과부화를 일으킬것 같네요

1. 실시간 검색 리스트 탑 10을 쿼리로 구한다.
2. 이것을 특정 db에 저장해둔다.
3. 페이지 로딩시 특정 db에 저장된 리스트 탑 10 만을 불러온다.
4. 1번, 2번 작업을 5분주기로 해준다.

이렇게 하고 싶은데 어떻게 짜야할까요??
 다음글 AA형 폐 건전지 대량으로 모을곳이 있을까요? (1)
 이전글 Alternative PHP Cache 에 대해 궁금합... (1)

댓글

변종원(웅파) / 2012/03/08 16:41:02 / 추천 0
cron 검색해서 적용하시면 되구요. (4번 작업) 
매뉴얼 참고  http://cikorea.net/user_guide_2.1.0/general/cli.html 


2. 쿼리결과를 db에 저장하고 다시 불러오면 부하가 있으니까요. 그런 것은 아예 html로 만들거나
파일에 json 또는 xml로 쓰는 것이 좋습니다.
한대승(불의회상) / 2012/03/08 16:51:55 / 추천 0
DB에 쿼리만 하시는 거라면 CI 사용 하지 않으셔도 될거 같습니다. ^^

$ crontab -e

0-59 * * * * /usr/bin/php /home/web/topchk.php

이 예제는 1분 마다 한번씩  topchk.php 를 실행 시켜 줍니다.
 
jake / 2012/03/08 18:50:03 / 추천 0
 답변 감사합니다! 한번 해보겠습니다 ㅎ
jake / 2012/03/08 18:59:15 / 추천 0
 웅파님

======================================================
2. 쿼리결과를 db에 저장하고 다시 불러오면 부하가 있으니까요. 그런 것은 아예 html로 만들거나
파일에 json 또는 xml로 쓰는 것이 좋습니다. 
====================================================== 

이 작업을 어떻게 하는지 알려주는 페이지가 어디 있을까요?
한대승(불의회상) / 2012/03/08 20:23:33 / 추천 0
웅파님이 언급 하신 부분은 캐슁의 일종 입니다.

CI를 이용하여 커맨드 라인 작업을 하신다면 DB 쿼리 캐슁을 살펴 보시면 좋을 듯 싶네요.

아래 URL을 참조 하세요.

http://www.codeigniter-kr.org/user_guide_2.1.0/database/caching.html
변종원(웅파) / 2012/03/09 13:18:04 / 추천 0
  http://cikorea.net/tip/view/104/page/1 참고하세요.

팁게시판에서 '쿼리'로 검색하시면 하나 더 나옵니다.
들국화 / 2012/03/12 14:49:20 / 추천 0
 MySQL Event 이용 하세요. ^^
mixiaoli / 2026/03/16 15:09:06 / 추천 0

지금 생각하신 구조는 맞습니다.
실시간 검색어 Top 10을 매 페이지마다 직접 집계하지 말고, 5분마다 한 번만 집계해서 저장해두고, 화면에서는 그 결과만 읽어오면 됩니다. CodeIgniter는 컨트롤러를 CLI로 실행할 수 있고, is_cli()로 크론 전용 실행도 구분할 수 있습니다. 또 Query Builder로 order_by(), limit()를 써서 Top 10 조회를 만들 수 있습니다.

다만 2번의 “특정 DB에 저장”은 꼭 DB 테이블일 필요는 없습니다.
CodeIgniter의 Cache Driver에는 get()save()가 있고, save()는 TTL(초)도 받을 수 있어서, 이런 Top 10 목록처럼 짧은 주기로 갱신되는 데이터는 캐시에 넣는 쪽이 더 단순합니다. 반대로 “이전 순위 기록”까지 남기고 싶으면 DB 테이블로 저장하는 게 맞습니다.

예를 들면 흐름은 이렇게 잡으면 됩니다.

  1. 검색어 집계 테이블에서 Top 10 조회

  2. 그 결과를 cache 또는 별도 테이블에 저장

  3. 화면에서는 cache/저장 테이블만 조회

  4. 크론이 5분마다 갱신

예시 코드는 이런 식입니다.


 
 
class Cron extends CI_Controller {

public function __construct()
{
parent::__construct();

if ( ! is_cli())
{
show_404();
}

$this->load->model('search_model');
$this->load->driver('cache', array('adapter' => 'file'));
}

public function update_keyword_rank()
{
$list = $this->search_model->get_top_keywords();

// 5분(300초) 캐시
$this->cache->save('top_keyword_10', $list, 300);

echo "ok\n";
}
}
 

모델은 대략 이렇게 하시면 됩니다.


 
 
class Search_model extends CI_Model {

public function get_top_keywords()
{
return $this->db
->select('keyword, COUNT(*) AS cnt', FALSE)
->from('search_log')
->group_by('keyword')
->order_by('cnt', 'DESC')
->limit(10)
->get()
->result_array();
}
}
 

페이지에서는 집계 쿼리를 다시 돌리지 말고, 저장된 결과만 읽습니다.


 
 
$this->load->driver('cache', array('adapter' => 'file'));

$data['top_keywords'] = $this->cache->get('top_keyword_10');

if ($data['top_keywords'] === FALSE)
{
$data['top_keywords'] = array();
}
 

그리고 크론에는 보통 이렇게 등록합니다.


 
 
*/5 * * * * /usr/bin/php /home/사이트경로/index.php cron update_keyword_rank
 

crontab분 시 일 월 요일 명령어 형식이고, */5 * * * * 는 5분마다 실행이라는 뜻입니다.

게시판 답변용으로 바로 쓰시려면 이렇게 쓰시면 자연스럽습니다.


 
 
생각하신 방식이 맞습니다.

매 페이지 로딩마다 실시간 검색어 TOP 10 집계 쿼리를 돌리면 부담이 될 수 있으니,
5분마다 한 번만 집계해서 저장해두고
화면에서는 저장된 결과만 읽는 구조로 가시면 됩니다.

구현은 보통 이렇게 합니다.

1. 검색 로그 테이블에서 TOP 10 집계 쿼리 작성
2. 그 결과를 별도 테이블 또는 cache 에 저장
3. 페이지에서는 그 저장된 결과만 출력
4. cron 에서 5분마다 갱신 실행

CI에서는 크론용 컨트롤러/메서드를 하나 만든 뒤
php index.php controller method
형태로 CLI 실행이 가능하므로,
이를 crontab 에 등록하시면 됩니다.

참고로 단순 TOP 10 출력만 목적이면
별도 DB 테이블보다 CI Cache Driver를 쓰는 방법이 더 간단합니다.
반대로 순위 이력까지 남기고 싶다면 테이블 저장이 더 좋습니다.