ORDER BY RAND() - 임의의 레코드를 뽑을 때

2014. 8. 31. 02:22 from Dev/sql

가끔 가다 여러 개의 레코드 중에서 임의의 하나를 뽑아내야 하는 경우가 있습니다. 

간단하게는 일단 레코드를 뽑아서 PHP 등등에서 랜덤으로 index를 결정해서 할 수가 있고, 복잡하게는(대상 레코드가 많으면) 미리 뽑아서 별도 파일이나 테이블에 저장한 후에 뽑는 방법도 있겠지요.

대상 레코드의 갯수가 많지 않은 경우에는 간단하게 SQL 에서 처리하는 방법이 있습니다 :


SELECT * FROM Member WHERE m_kind = 1 ORDER BY RAND() LIMIT 1;


주의할 점은, 절대 scalable 하지 않다는 것.. temporary table을 생성하고 소트를 하기 때문에 레코드 갯수가 많은 때 사용하면 안되겠습니다. 하지만 몇 개만 뽑아서 할 경우에 간단히 사용하기에는 좋은 방법일 수 있습니다. ^^;;

Posted by banasun :

[sql] pagination, 페이지 나누기

2014. 2. 25. 10:16 from Dev/sql


보통 페이지 나누어서 결과를 가져오는 경우

SELECT * FROM message ORDER BY id DESC LIMIT 10000, 20

이렇게 쓰게 된다. 그러나 이 경우,10000개의 row는 그냥 버리고 그 뒤의 20개만 가져오는 문제가 생기기 때문에 퍼포먼스라는 측면에서는 고민이 될 수밖에 없다.

결국, OFFSET이 커지면 커질수록 필요없는 데이터가 메모리에 쌓였다 버려진다. 동접이 얼마 안되면야 서버가 일하는 거니 나랑 상관없다지만, 동접이 얼마 이상 된다면 병목현상이 발생할 수밖에 없고, 개발자는 회사에서 까이는 현상이 발생한다;;

해결책 - 

  1. 뒷 페이지까지 이동하지 않도록 한다 (초간단 해결책!!) : 처음에 5~10페이지만 보여주고, 그 이전 데이터는 검색을 해서 찾아가는 UI를 만들자. 
  2. 큰 OFFSET이 필요한 경우 WHERE절을 이용해서 어디부터 시작할지를 정해준다. (예: 직전 페이지 id를 남겨놓았다가 WHERE id > 324790 LIMIT 20 이런 식으로..)


Posted by banasun :