Last Updated on 1월 20, 2024 by Jade(정현호)
안녕하세요
이번 글은 MySQL 에서의 NOW 함수와 SYSDATE 함수의 차이를 간단하게 살펴보려고 합니다.
Contents
개요
MySQL 에서는 현재 시각을 조회하는 함수로 NOW() 와 SYSDATE 함수가 있으며 현재의 시간을 반환하는 같은 기능을 수행합니다
SELECT NOW();
SELECT SYSDATE();
다만 2개의 시간 조회 함수는 조회 방법에 따른 다른 시간 결과가 출력될 수 있으며 성능적 차이점이 발생되게 됩니다.
시간 결과 차이
SYSDATE() 는 같은 쿼리 안에서도 조회 시점에 따라서 결과가 달라지게 됩니다.
mysql> SELECT NOW(),SLEEP(5),NOW(); +----------+----------+----------+ | NOW() | SLEEP(5) | NOW() | +----------+----------+----------+ | 12:37:02 | 0 | 12:37:02 | +----------+----------+----------+ mysql> SELECT SYSDATE(),SLEEP(5),SYSDATE(); +-----------+----------+----------+ | SYSDATE() | SLEEP(5) | SYSDATE()| +-----------+----------+----------+ | 12:37:05 | 0 | 12:37:10 | +-----------+----------+----------+
* 가로 사이즈를 줄이기 위해서 날짜는 제외하였습니다
위와 같이 5초의 대기한 후 각각 조회를 해보면 NOW() 는 같은 SQL 문장에서 같은 시간을 반환하지만 SYSDATE() 는 대기한 5초 동안의 차이가 발생하는 것을 확인할 수 있습니다.
그래서 SYSDATE() 아래의 잠재적인 문제를 내재되어 있습니다.
- SYSDATE() 함수를 사용한 DML 수행 시 Replication 환경에서 Slave 에 정상적인 복제가 이루어 지지 않게 될 수도 있음
- SYSDATE() 는 NOW() 에 비해 인덱스를 효율적으로 사용하지 못할 수 있음
인덱스 사용시 차이점
SYSDATE() 는 NOW()는 인덱스를 통한 조회시에도 차이점이 있습니다.
샘플 테이블 과 플랜 조회 쿼리
-- 샘플 테이블 생성 CREATE TABLE tb_test ( col1 int NOT NULL AUTO_INCREMENT, col2 varchar(20) DEFAULT NULL, col3 int DEFAULT NULL, regdt datetime NOT NULL, PRIMARY KEY (col1), KEY ix_1(col3, regdt) ) ENGINE=InnoDB; -- NOW() 사용 explain SELECT * from tb_test where col3=10 and regdt>now(); -- SYSDATE() 사용 explain SELECT * from tb_test where col3=10 and regdt>sysdate();
플랜 차이 비교
select * from tb_test where col3=10 and regdt>now(); +--+--------+-------+------+---------+ |id|sel_type|table | key | key_len | +--+--------+-------+------+---------+ | 1|SIMPLE |tb_test| ix_1 | 10 | +--+--------+-------+------+---------+ select * from tb_test where col3=10 and regdt>sysdate(); +--+--------+-------+------+---------+ |id|sel_type|table | key | key_len | +--+--------+-------+------+---------+ | 1|SIMPLE |tb_test| ix_1 | 5 | +--+--------+-------+------+---------+
* 가로 사이즈를 줄이기 위해서 편집되어 있습니다.
2개 함수의 차이점
SYSDATE() 함수는 호출될 때마다 다른 값을 반환하게 됨에 따라 사실상 상수화 되어 처리가 되지 못하는 부분이 있습니다.
그래서 위와 같은 쿼리에서 아래 SYSDATE() 함수를 사용하여 WHERE 절을 비교할 때, 매번 SYSDATE() 를 호출해야 합니다
또한 위의 예제에서 결합 인덱스 로 구성된 col3+regdt 컬럼 중 인덱스 스캔 시 2개의 컬럼을 모두 사용하였는지 1개의 컬럼만 사용되었는지에 따라 플랜상 key_len 수치 다른 점을 확인할 수 있습니다
Conclusion
이와 같이 MySQL의 2개 시간 반환 함수는 사용에 따라서 차이를 보이게 됩니다.
1개의 트랜잭션 내에 다수의 쿼리가 포함되어 있고 중간중간에 시간을 조회하거나 조회된 값으로 데이터 입력 또는 변경 시 등 처음시작과 끝이 동일 해야 한다면 NOW() 를 사용해야 할 것입니다.
그리고 의도하여 중간중간 조회시의 시간을 확인이나 조회 시점의 시간이 필요하다면 SYSDATE() 를 사용해야 할 것입니다.
SYSDATE() 를 NOW() 함수처럼 처리하도록 설정할 수 있습니다.
MySQL 설정 파일(my.cnf)에 sysdate-is-now 시스템 변수를 를 추가하면 SYSDATE() 도 NOW() 와 같은 형태로 수행되게 됩니다
Ref Book
• Real MySQL[Iink]
연관된 다른 글
Principal DBA(MySQL, AWS Aurora, Oracle)
핀테크 서비스인 핀다에서 데이터베이스를 운영하고 있어요(at finda.co.kr)
Previous - 당근마켓, 위메프, Oracle Korea ACS / Fedora Kor UserGroup 운영중
Database 외에도 NoSQL , Linux , Python, Cloud, Http/PHP CGI 등에도 관심이 있습니다
purityboy83@gmail.com / admin@hoing.io