쿼리 캐시
-
쿼리 캐시란,
SELECT
쿼리문을 이용하여 조회한 값을 저장하고 있다가, 같은 쿼리 문을 요청하였을 때 미리 캐싱된 값을 반환하는DBMS
기능이다. -
일반적인 웹사이트와 같이 쓰기 (
WRITE
)보다, 읽는 (READ
) 횟수가 많은 환경에서 유용하다. -
하지만, 멀티 코어 시스템 및 처리량이 높은 환경에서는 확장성이 좋지 않으므로 기본적으로 사용되지 않도록 설정된다.
쿼리 캐시 기능을 사용하기
-
쿼리 캐시 기능을 사용할 수 있는지 확인하려면, 기본적으로
have_query_cache
설정이 되어 있어야 한다. -
설정이 되어있는지 확인하고 싶다면, 아래와 같은 쿼리 문을 입력한다.
SHOW VARIABLES LIKE 'HAVE_QUERY_CACHE'
- 조회 결과
YES
로 나온다면, 쿼리 캐시 기능을 사용할 수 있다는 뜻이다.
SHOW VARIABLES LIKE 'QUERY_CACHE_TYPE'
- 그 다음에는 현재 시스템에서 쿼리 캐시 기능을 사용하고 있는지를 조회해 볼 것이다. 위의 쿼리 결과가
ON
으로 나온다면 이미 쿼리 캐시 기능을 적용하고 있다는 뜻이다.
쿼리 캐시가 되지 않는 경우
아래와 같은 함수를 사용하면, 기본적으로 쿼리가 캐싱되지 않는다.
BENCHMARK()
CONNECTION_ID()
CONVERT_TZ()
CURDATE()
CURRENT_DATE()
CURRENT_TIME()
CURRENT_TIMESTAMP()
CURTIME()
DATABASE()
ENCRYPT() (one parameter)
FOUND_ROWS()
GET_LOCK()
LAST_INSERT_ID()
LOAD_FILE()
MASTER_POS_WAIT()
NOW()
RAND()
RELEASE_LOCK()
SLEEP()
SYSDATE()
UNIX_TIMESTAMP()
(no parameters)
USER()
UUID()
UUID_SHORT()
- 또한 쿼리에 아래와 같은 구문이 있을 경우 쿼리가 캐싱되지 않는다.
SELECT SQL_NO_CACHE ...
SELECT ... INTO OUTFILE ...
SELECT ... INTO DUMPFILE ...
SELECT ... FOR UPDATE
SELECT * FROM ... WHERE autoincrement_column IS NULL
SELECT ... LOCK IN SHARE MODE
쿼리 캐시 크기를 제한하기
-
쿼리 캐시 크기를 제한하기 전에, 우선 쿼리 캐시 크기 설정을 살펴보자.
-
위의 설정을 통해서
query_cache_size
값을 설정할 수 있다. -
쿼리의 빈도수가 적고, 데이터가 많이 조회되는 쿼리가 있을 것이다. 이런 경우에는 캐싱을 할 필요가 없으므로,
query_cache_limit
옵션으로 크기를 설정해서 특정 결과값의 용량이 설정해놓은 값이 넘으면 캐싱하지 않도록 설정을 할 수 있다.
캐시 설정 및 의미
SHOW STATUS LIKE 'Qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 1158 |
| Qcache_free_memory | 3760784 |
| Qcache_hits | 31943398 |
| Qcache_inserts | 42998029 |
| Qcache_lowmem_prunes | 34695322 |
| Qcache_not_cached | 652482 |
| Qcache_queries_in_cache | 4628 |
| Qcache_total_blocks | 11123 |
+-------------------------+----------+
-
위와 같은 쿼리를 입력하면, 쿼리 캐싱과 관련된 설정 값들이 나오게 된다.
-
중요한 옵션값만 확인하자면,
Qcache_inserts
는 현재, 캐싱된 쿼리의 값을 의미한다. -
Qcache_hits
는 쿼리를 캐싱하여, 캐싱된 값을 반환한 값을 의미한다. -
Qcache_lowmem_prunes
는 메모리 값이 부족하여, 캐시에서 이전에 있던 값을 제거한 값이다. -
Qcache_lowmem_prunes
값을 줄이려면 앞서 말했던,query_cache_limit
값을 적절히 설정해주면 될 것이다.
결론
-
그 밖에도,
query_cache_wlock_invalidate
옵션을 끄면,WRITE
락이 걸려있더라도, 캐싱된 값을 반환하게 하여, 경합 상태에서도 기다리지 않고 값을 읽을 수 있다. -
캐시된 쿼리를 잘 이용하면, 성능을 높일 수 있을 것이다.
-
실제
SQL
문은 대소문자를 구분하지 않지만, 캐싱된 쿼리 값을 반환받기 위해서는 대소문자까지 같아야 하므로, 팀 내에서 쿼리문을 통일성 있게 작성하는 노력을 해야할 것이다.그 밖에도 동일한 쿼리라는 것을 인식하려면 여러 값들이 일정해야한다. 이는 아래 내용을 참조하도록 하자.
- 쿼리 캐시 값의 크기를 크게 늘리면, 읽기 속도는 빨라지겠지만, 락 경합 때문에 쓰기 속도는 느려질 수 있다. 최적값을 찾아서 적용하는 것이 좋다.