[mysql] 현재로부터 6시간 이내의 record를 select 하기

2015. 3. 19. 23:22 from Dev/sql

오늘은 SQL query문 중 기초적인 부분에 대해서 써볼까 합니다. 물론 오늘 한 작업 중 한 가지 소스이지요 ㅋㅋ

DATETIME 필드를 기준으로 현재로부터 6시간 이내에 발생한 record를 불러오는 겁니다.

MYSQL에는 DATE_ADD()라는 함수가 있습니다. 이 함수를 이용하는 거지요.


SELECT * FROM foo WHERE created_at > DATE_ADD(now(), INTERVAL -6 HOUR)


지금 현재 시각 now() 에서 6시간의 INTERVAL을 빼주었으니 현재에서 6시간 이내가 되는 거지요.

HOUR 대신에 MINUTE, SECOND, DAY 등으로 할 수도 있으니 (쓰다 보니 DAY를 이용한 거는 예전에 포스팅을 했던 것 같기도..) 응용해서 쓰시면 됩니다.

Posted by banasun :

[MySQL] CURDATE(), CURRENT_DATE(), INTERVAL 을 이용해서 어제 날짜 가져오기

2014. 9. 15. 14:26 from Dev/sql

단순한 팁인데, SQL문에 날짜 기준을 삼기 위해서 PHP 등에서 날짜를 계산해서 전달하는 것보다는 SQL 자체에서 계산해주는 것이 로직 면에서 더 보기 좋다고 봅니다(개인적으로). 

어제 날짜를 SQL문에 넣으려면 다음과 같이 해줍니다:


select current_date() - interval 1 day;


아니면 


SELECT DATE_ADD(CURDATE(), INTERVAL -1 DAY);


참고로, current_date()와 CURDATE()는 같은 함수입니다.

Posted by banasun :

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 :