본문 바로가기
서버구축 (WEB,DB)

MySQL에서 Query Cache 사용하기

by 날으는물고기 2008. 10. 27.

MySQL에서 Query Cache 사용하기

Query Cache


MySQL 서버에서 Query Cache를 사용하고 있으며, SELECT 문을 수행한 결과의 텍스트 내용이 query cache에 저장하게 된다. (mysqld --query_cache_size=#을 지정하여 데몬을 시작한 경우)

앞서 진행했던 것과 동일한 query를 나중에 다시 받게 되면, 서버는 전에 query cache에 저장한 내용에서 클라이언트에 보낸다.

query cache는 테이블 내용이 자주 바뀌지 않거나, 동일한 쿼리를 반복하는 경우에는 아주 유용하다.

Query Cache에서 다음 두 문장은 다르게 처리된다.

        mysql> SELECT * FROM tbl_name;
        mysql> select * from tbl_name;

query cache에서 결과를 받아오려면 두 쿼리가 바이트 단위로 동일해야 하기 때문에 위 두 문장은 다르게 해석된다.

또한 Query가 서로 다른 데이터베이스를 사용한 경우, 서로 다른 프로토콜 버전을 사용한 경우, 서로 다른 디폴트 문자세트를 사용한 경우는 동일하지 않은 쿼리로 처리하여 query cache에서 결과를 받아 오지 않게 된다.

SELECT SQL_CALC_FOUND_ROWSSELECT FOUND_ROWS()와 같은 쿼리에도 이미 query cache에 직전의 정보가 담겨 있기 때문에 query cache로부터 결과를 가져온다.

쿼리 결과를 query cache에서 받아 오는 경우에는 show status 변수인 Com_select는 증가하지 않지만, Qcache_hits는 증가한다.

        mysql> show status like 'Com_select';
        mysql> show status like 'Qcache_hits';

INSERT, UPDATE, DELETE, TRUNCATE, ALTER, DROP TABLE, DROP DATABASE 문에 의해서 테이블이 변경되면, 이들 테이블로부터 사용했던 모든 캐시화된 쿼리는 무용지물이 되므로 query cache의 cache에서 제거된다.
(MRG_MyISAM 형 테이블도 포함됨)

트랜젝션 테이블인 InnoDB형 테이블이 COMMIT에 의해서 변경된 경우도
query cache의 내용은 무용지물이 된다.

다음에 나열된 함수가 포함된 경우도 query cache에 저장되지 않는다.


User-Defined Functions  GET_LOCK        MASTER_POS_WAIT
CURRENT_TIMESTAMP       CURDATE         ENCRYPT
UNIX_TIMESTAMP          CONNECTION_ID   RELEASE_LOCK
NOW                     CURTIME         CURRENT_TIME
LAST_INSERT_ID          USER            FOUND_ROWS
LOAD_FILE               SYSDATE         CURRENT_DATE
DATABASE                RAND            BENCHMARK


또한 사용자 변수가 있는 경우도 query cache에 저장되지 않으며, mysql system 데이터베이스를 참조한 다음과 같은 문장도 query cache에 저장되지 안는다.


  SELECT ... IN SHARE MODE
  SELECT ... INTO OUTFILE ...
  SELECT ... INTO DUMPFILE ...
  SELECT * FROM AUTOINCREMENT_FIELD IS NULL


비록 FOUND_ROWS()를 실행하여 바른 값이 반환되더라도 이는 직전의 쿼리가 query cache에 저장된 값이 출력되는 것이다.

쿼리가 어떤 테이블도 사용하지 않은 경우, 임시 테이블을 사용한 경우, 사용자가 테이블의 컬럼에 권한이 없는 경우도 쿼리 결과가 query cache에 저장되지 않는다.

쿼리 결과를 query cache에서 가져오기 전에 MySQL은 해당 데이터베이스와 테이블에 대한 SELECT 권한을 먼저 체크한다.

query_cache_size의 크기가 '0'이라면, 이는 query cache가 허용되지 않은 경우이다.(디폴트 임)

mysql> show variables like 'query_cache_size';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| query_cache_size | 0     |
+------------------+-------+
1 row in set (0.00 sec)

mysql>

이처럼 query cache가 설정되지 않았다면, mysqld를 시작할 때 옵션으로 다음과 같이 지정한다.

  --query_cache_limit=# (디폴트: 1MB)
  --query_cache_min_res_unit=# (디폴트: 4KB)
  --query_cache_size=# (디폴트: 0)
  --query_cache_type=#


여기서  query_cache_type은 다음과 같이 수치로 지정한다.

Option 설 명 0 OFF로 query cache를 사용하지 않음 1 ON으로 SELECT SQL_NO_CACHE...에 의한 쿼리를 제외하고 query cache를 허용함 2 DEMAND로 SELECT SQL_CACHE...에 의해서만 사용함



QUERY CACHE을 지정하여 시스템 관리자가 데몬을 구동하면 된다.

【예제】query_cache_size를 지정한 구동 스크립트
# cat /etc/rc2.d/S99mysqld
/export/home/mysql/bin/mysqld_safe \
   --user=mysql --query_cache_size=8M --log-bin &

#
mysql> show variables like 'query_cache_size';
+------------------+---------+
| Variable_name    | Value   |
+------------------+---------+
| query_cache_size | 8388608 |
+------------------+---------+
1 row in set (0.00 sec)

mysql> select * from aa;

mysql> select * from aa;

mysql> show status like 'Com_select';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select    |

1

     |
+---------------+-------+
1 row in set (0.00 sec)

mysql> show status like 'Qcache_hits';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Qcache_hits   |

1

     |
+---------------+-------+
1 row in set (0.02 sec)

mysql>

다음 명령처럼 실행하면, query cache의 디폴트 값에서 내부적으로 변경할 수 있다.

  QUERY_CACHE_TYPE=OFF | ON | DEMAND
  QUERY_CACHE_TYPE=0   | 1  | 2


여기서 사용되는 옵션의 의미는 다음과 같다.

Option 설 명 0 또는 OFF query cache를 사용하지 않음 1 또는 ON SELECT SQL_NO_CACHE...에 의한 쿼리를 제외하고 query cache를 허용함 2 또는 DEMAND SELECT SQL_CACHE...에 의해서만 사용함



SELECT 문에서 사용되는 Query Cache 옵션은 다음과 같다.

SQL_CACHE QUERY_CACHE_TYPE이 DEMAND이면 query한 내용이 cache됨
QUERY_CACHE_TYPE이 ON이면 디폴트이고,
QUERY-CACHE_TYPE이 OFF이면 query한 내용이 cache 안됨
SQL_NO_CACHE query를 non-cachable로 하여 cache에 저장하지 않음



FLUSH QUERY CACHE 명령으로 query cache의 조각을 재정리하지만
  query cache에 존재하는 어느 query도 제거해 없애지 않는다.

또한 FLUSH TABLES도 query cache를 flush 시킨다.

RESET QUERY CACHE 명령은 query cache에 존재하는 모든 query 내용을 제거한다.

현재의 MySQL 버전에서 서버가 query cache의 지원여부는 have_query_cache 변수로
확인이 가능하다.

mysql> show variables like 'have_query_cache';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| have_query_cache | YES   |
+------------------+-------+
1 row in set (0.00 sec)

mysql>

그리고 SHOW STATUS로 query cache의 퍼포먼스를 알아 볼 수 있는 변수는 다음과 같다.

variable 의 미 Qcache_queries_in_cache cache에 등록된 query의 수 Qcache_inserts cache에 추가된 query의 수 Qcache_hits query cache에서 받아온 횟수 Qcache_lowmem_prunes low memory 때문에 cache에서 삭제된 query 수 Qcache_not_cached QUERY_CACHE_TYPE나 not cachable 때문에 query한 정보가 cache에 저장되지 않는 수 Qcache_free_memory query cache의 여유 메모리량 Qcache_free_blocks query cache의 여유 메모리 블록 수 Qcache_total_blocks query cache에 할당된 총 블록 수


 

Query Cache는  MySQL에서 4.0.1 부터 지원 함

간단히 쿼리 결과에 대해 캐슁을 하여 속도 향상을 시행함

*/etc/my.cnf 적용 예 *

vi /etc/my.cnf

# 쿼리 캐싱 제한 메모리
set variable = query_cache_limit=10M

# 쿼리 캐싱 메모리 사이즈
set variable = query_cache_size=30M

# Query Cache 사용 타입

# 0 : 사용 안함 
# 1 : 모든 쿼리에 대해 캐싱하고
#     select문에서 seelct sql_no_cache를 쓰면 사용 안함

# 2 : 쿼리 캐쉬 선택 함 
#     slq 사용 예 : select sql_cache count(*) from board;

set variable = query_cache_type=1 

728x90

댓글