2016년 9월 23일 금요일
Mysql ( Order by Rand() 튜닝 방법 )
Order by Rand() 구문 튜닝 방법
* 이슈
-> Order by Rand 구문은 테이블의 건수가 증가할수록 Sorting 부하 증가로 DB 에 지속적인 부하를 가중시킬 수 있음. 튜닝이 필요함. 보통 게임 서비스에서 친구 추천이나,
PVP 대상을 찾아 낼때 효과적일 수있음.
* 튜닝 전 SQL
[ 원본 쿼리 ]
SELECT id FROM random_test
WHERE level >= ? AND level <= ?
AND last_time >= ?
AND id != ?
AND slotindex != ?
order by rand()
limit 100;
[ AS-IS 수행 시간 ]
평균 0.41 ( Cpu 사용율 높음)
* 튜닝 후 SQL
-> Order by Rand 를 사용하나, 미리 500건으로 축소하여 사용하므로 Sorting 최소화
[ 튜닝 쿼리 ]
SELECT id ,level,last_time,slotindex
FROM ( SELECT id ,level,last_time,slotindex
FROM ( SELECT min_num + (max_num - min_num + 1 - 500) * RAND() AS start
FROM (select
(select id
from random_test t use index for order by (idx_id)
WHERE level >= ? AND level <= ?
AND last_time >= ?
AND id != ?
AND slotindex != ? order by id desc limit 1 ) max_num ,
(select id
from random_test t use index for order by (idx_id)
WHERE level >= ? AND level <= ?
AND last_time >= ?
AND id != ?
AND slotindex != ? order by id asc limit 1 ) min_num
)NUM_CHECK
)AS init
JOIN random_test y
WHERE y.id > init.start
and level >= ? AND level <= ?
AND last_time >= ?
AND id != ?
AND slotindex != ?
ORDER BY y.id
LIMIT 500
) z ORDER BY RAND()
LIMIT 100;
[TO-BE 수행 시간 ]
평균 0.01초 ( Cpu 사용율 낮음)
-> 2차 튜닝 예상건
위는 1차 튜닝이고, 만약 테스트 시에 위 쿼리으로 인해 부하가 커진다면 , 2차 방안으로 위 쿼리에서 Order by RAND 를 삭제 하면 Sorting 부하를 모두 제거 할 수 있습니다.
다만, 위 쿼리는 500건 이내에서 Random 하게 친구 목록 리스트를 변경하지만 Order by Rand 를 삭제 할 경우 500 건 단위로는 목록이 변할 수 있지만
500건 이내에서는 계속 동일한 순서로 친구목록이 나오게 되며, 비슷한 리스트가 자주 나올수있습니다.
피드 구독하기:
댓글 (Atom)
댓글 없음:
댓글 쓰기