쿼리 캐시


  • 쿼리 캐시란, 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

쿼리 캐시 크기를 제한하기


Screen Shot 2021-06-04 at 4 03 22 PM

  • 쿼리 캐시 크기를 제한하기 전에, 우선 쿼리 캐시 크기 설정을 살펴보자.

  • 위의 설정을 통해서 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문은 대소문자를 구분하지 않지만, 캐싱된 쿼리 값을 반환받기 위해서는 대소문자까지 같아야 하므로, 팀 내에서 쿼리문을 통일성 있게 작성하는 노력을 해야할 것이다.그 밖에도 동일한 쿼리라는 것을 인식하려면 여러 값들이 일정해야한다. 이는 아래 내용을 참조하도록 하자.

Screen Shot 2021-06-04 at 4 28 16 PM

  • 쿼리 캐시 값의 크기를 크게 늘리면, 읽기 속도는 빨라지겠지만, 락 경합 때문에 쓰기 속도는 느려질 수 있다. 최적값을 찾아서 적용하는 것이 좋다.

참고 문헌

>> Home