rand 쿼리에서 부하가 생기는데 방법있나요?
본문
SELECT * FROM g5_write_pds ORDER BY RAND() LIMIT 12
게시물이 많아서. 이 쿼리에서 부하 발생하는데요.
좋은방법 있을까요? 예를들면 최근 500개중 랜덤으로 12개 부르고
이런방식이 잇을까요?
답변 6
코드가 몇줄 더 추가 되지만 가장 손쉬운 방법이라 생각 되는 것은
wr_id를 미리 랜덤하게 구해서 추출하면 될 것입니다
$row=sql_fetch("select max(wr_id) as id from g5_write_pds");
$wrArr = range(1, $row['id']);
shuffle($wrArr);
$wrArr2 = array_slice($wrArr, 0,20); //--게시물이 삭제되어 wr_id가 없는 경우도 있으므로 여유있게 추출
$idStr = implode(',', $wrArr2);
$result = sql_query("SELECT * FROM g5_write_pds where wr_id IN($idStr) "); //추출한 리스트에서 12개만 사용하면 됨
-----------------------
ORDER BY RAND() 보다 10배 이상 빠를 것입니다
현실적으로 가장 쉽게 적용가능한 방법은
1. 게시물 등록수가 많다고 하니, wr_datetime 에 index 를 추가
2. 최근 1일 이나 2일정도로 날짜 범위를 추가하여 데이타를 추출
table 인덱스 추가
ALTER TABLE g5_write_pds ADD INDEX wr_datetime(wr_datetime);
php 소스코드 수정
$before_1day_datetime = date("Y-m-d H:i:s", strtotime("-1 days"));
$now_datetime = date("Y-m-d H:i:s");
$sql = "SELECT *
FROM g5_write_pds
WHERE wr_datetime BETWEEN '{$before_1day_datetime}' AND '{$now_datetime}'
ORDER BY RAND()
LIMIT 12
";
https://tosska.com/how-to-tune-order-by-rand-limit-1-sql-statement/
CTE를 쓰는 관계로
MySQL 8이상에서 가능
참고하세요
위의 쿼리는 pds에 존재하는 모든 데이타를 랜덤으로 섞어서 그중 12개를 뽑아오는것이라서
데이타가 많아 질수록 느려집니다.
where 절에 추출할 기준을 축소시켜주는게 중요하고
random 으로 섞는것을 모수의 대상을 어떻게 한후에 그중 랜덤을 뽑을지는
기준점을 적절하게 잡아주는게 좋습니다.
예를 들어 번호들만 500개를 추출하고
php로직에서 랜덤 12개를 선택하게하고
랜덤으로 선택된 12개의 번호만을 대상으로 데이타를 가져오는것도 방법입니다.
rand 쿼리는 접속자가 많은 사이트에선 가급적 사용 안하는게 좋습니다.
캐시를 사용하는걸 추천드립니다.(그누보드 파일 캐시 또는 redis 캐시)
crontab 을 사용할수 있는 환경이라면 미리 생성해두는것도 좋은 방법입니다.