Zero to Hero
article thumbnail
Published 2021. 5. 29. 19:54
Real MySQL 01 Review

쿼리 캐시

- 타 DBMS에 없는 MySQL의 독특한 기능

- 실행된 결과를 쿼리 캐시에 담아 두고, 동일한 쿼리 요청이 왔을 때 간단하게 쿼리 캐시에서 찾아서 바로 결과를 내려 줌

- 쿼리를 캐싱하는 것이 아니라 쿼리의 결과를 메모리에 캐싱하는 기능

- 쿼리 캐시는 기본적으로 KEY, VALUE의 Map 형태이고 KEY가 쿼리, VALUE가 해당 쿼리에 대한 결괏값이다.

 

쿼리 캐시를 이용해 결과를 얻을 때 확인할 것

1. 요청된 쿼리 문장이 쿼리 캐시에 존재하는가?

Map에서 입력된 쿼리로 된 KEY가 있는지 찾고 결과를 반환하는 굉장히 단순한 방식이기 때문에 쿼리의 대, 소문자 및 공백에도 반응한다.

그러므로 비슷한 작업을 하는 쿼리는 하나의 쿼리로 통일해 문자열을 관리해주는 것이 좋다.

 

2. 해당 사용자가 그 결과를 볼 수 있는 권한을 가지고 있는가?

쿼리 캐시에 저장되어 있는 쿼리라도 해당 사용자가 해당 쿼리를 수행하고 결과를 볼 수 있는 권한이 있는지에 대한 확인이 필요하다.

 

3. 트랜잭션 내에서 실행된 쿼리인 경우 가시 범위 내에 있는 결과인가?

InnoDB의 모든 트랜잭션은 각 트랜잭션 ID를 가지게 되고, 이는 순차적으로 증가하는 6바이트 숫자 값이다.

트랜잭션 격리 수준을 준수하기 위해 각 트랜잭션은 자신의 ID보다 ID 값이 큰 트랜잭션에 변경한 작업 내역이나 쿼리 결과는 참조할 수 없다.

쿼리 캐시도 결과를 만들어 낸 트랜잭션의 ID가 가시 범위 내에 있을 때만 사용할 수 있다.

 

4. 호출할 때마다 달라지는 내장 함수(CURRENT_DATE(), SYSDATE() 등)를 포함하는지

결과적으로 이런 건 쿼리 캐시로 사용하기 적합하지 않다. 호출할 때마다 값이 변경되기 때문이다.

 

5. Prepared Statement 관련

Prepared Statement는 프로그램 코드 레벨에서 사용하는 개념이다. (JAVA 등...)

즉 DBMS에는 실제로?를 포함한 쿼리 형태로 사용되지 않고, 이런 쿼리 또한 쿼리 캐시에 저장할 수 없다.

하지만 5.1 버전부터는 서버사이드 PREPARED STATEMENT라는 개념이 등장해서 사용할 수 있는 것 같다.

 

6. 캐시가 만들어지고 난 이후 해당 데이터가 다른 사용자에 의해 변경되지 않았는가?

정리하면 캐시가 만들어지고 해당 결과가 다른 트랜잭션에 의해 변경되었다면, 그 캐시에 대한 결과는 무의미하기 때문에 버려야 한다.

버린다는 것은 쿼리 캐시 안의 데이터를 무효화한다는 것이고 이 또한 많아지면 아무리 메모리라고 하더라도 상당한 시간이 소모된다.

또 쿼리 캐시는 여러 스레드에서 동시에 변경할 수 없다는 특징이 있어서 쿼리 캐시의 적절한 크기를 설정해주는 것도 중요하다.

 

7. 쿼리 결과가 캐싱하기 너무 크지 않은가?

너무 크면 쿼리 결과 하나가 쿼리 캐시 영역을 전부 잡아먹으니깐 비효율적이다.

쿼리가 결과를 만들어내는 데 많은 시간과 자원이 필요하지만 만들어진 결과의 크기가 작을수록 효율적으로 사용할 수 있다.

보통 마지막에 GROUP BY, DISTINCT, COUNT 등 결과 자체의 사이즈가 작은 쿼리가 사용하기 적합하다고 볼 수 있다.

 

'Review' 카테고리의 다른 글

자바 ORM 표준 JPA 프로그래밍 - 기본편  (0) 2021.07.17
Real MySQL 02  (0) 2021.05.29
친절한 SQL 튜닝 05  (2) 2021.05.08
웹 엔지니어가 알아야 할 인프라의 기본 01  (0) 2021.05.08
SQL 레벨업 03  (0) 2021.05.02
profile

Zero to Hero

@Doljae

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!