>데이터 베이스 >MySQL 튜토리얼 >MySQL 쿼리 캐시 최적화에 대한 고급 설명

MySQL 쿼리 캐시 최적화에 대한 고급 설명

coldplay.xixi
coldplay.xixi앞으로
2021-03-19 09:58:552446검색

MySQL 쿼리 캐시 최적화에 대한 고급 설명

MySQL 쿼리 캐시 최적화

  • 1 개요
  • 2 작업 프로세스
  • 3 쿼리 캐시 구성
  • 4 쿼리 캐시 켜기
  • 5 쿼리 캐시 SELECT 옵션
  • 6 쿼리 캐시 실패

(무료 학습 추천: mysql 동영상 튜토리얼)

1. 개요

Mysql 쿼리 캐시를 활성화하면 서버가 이를 캐시에서 직접 검색합니다. 결과를 읽어 데이터가 수정되면 이전 캐시가 무효화됩니다. 자주 수정되는 테이블은 쿼리 캐싱에 적합하지 않습니다.

2. 작업 프로세스

MySQL 쿼리 캐시 최적화에 대한 고급 설명
1. 클라이언트가 서버에 쿼리를 보냅니다.
2. 서버는 먼저 쿼리 캐시에 도달하면 저장된 결과를 즉시 반환합니다. 캐시에. 그렇지 않으면 다음 단계로 들어갑니다.
3. 서버는 SQL 구문 분석 및 전처리를 수행한 후 최적화 프로그램이 해당 실행 계획을 생성합니다.
4. MySQL은 생성된 실행 계획을 기반으로 쿼리를 실행하기 위해 스토리지 엔진의 API를 호출합니다.
5. 결과를 클라이언트에 반환합니다.

3. 쿼리 캐시 구성

  1. 현재 MySQL 데이터베이스가 쿼리 캐싱을 지원하는지 확인하세요.
 SHOW VARIABLES LIKE 'have_query_cache';
mysql> SHOW VARIABLES LIKE 'have_query_cache';+------------------+-------+| Variable_name    | Value |+------------------+-------+| have_query_cache | YES   |+------------------+-------+1 row in set (0.26 sec)

는 현재 데이터베이스가 쿼리 캐싱을 지원함을 나타냅니다.

  1. 현재 MySQL에 쿼리 캐싱이 활성화되어 있는지 확인하세요.
mysql>  SHOW VARIABLES LIKE 'query_cache_type';+------------------+-------+| Variable_name    | Value |+------------------+-------+| query_cache_type | OFF   |+------------------+-------+1 row in set (0.01 sec)

는 쿼리 캐시가 현재 활성화되어 있지 않음을 나타냅니다.

  1. 쿼리 캐시 점유 크기를 확인하세요.
mysql> SHOW VARIABLES LIKE 'query_cache_size';+------------------+----------+| Variable_name    | Value    |+------------------+----------+| query_cache_size | 16777216 |+------------------+----------+

는 현재 쿼리 캐시가 16777216바이트(약 1.5MB)를 점유하고 있음을 의미합니다. 쿼리 캐시의 크기를 늘리려면 query_cache_size를 사용하세요.

  1. 쿼리 캐시의 상태 변수 보기:
mysql> SHOW STATUS LIKE 'Qcache%';+-------------------------+----------+| Variable_name           | Value    |+-------------------------+----------+| Qcache_free_blocks      | 1        || Qcache_free_memory      | 16768680 || Qcache_hits             | 0        || Qcache_inserts          | 0        || Qcache_lowmem_prunes    | 0        || Qcache_not_cached       | 29       || Qcache_queries_in_cache | 0        || Qcache_total_blocks     | 1        |+-------------------------+----------+

각 변수의 의미는 다음과 같습니다.

매개변수 의미
Qcache_free_blocks 숫자 사용 가능한 메모리 블록 수 쿼리 캐시
Qcache_free_memory 쿼리 캐시에 사용 가능한 메모리 양
Qcache_hits 쿼리 캐시 적중 수
Qcache_inserts 쿼리 캐시에 추가된 쿼리 수
Qcache_lowmen_prunes 메모리 부족으로 쿼리 캐시에서 삭제됨 쿼리 개수
Qcache_not_cached 캐시할 수 없는 쿼리 개수(query_cache_type 설정으로 인해 캐시할 수 없거나 캐시되지 않는 쿼리 개수)
Qcache_queries_in_cache 쿼리 캐시에 등록된 쿼리 개수
Qcache_total _blocks 쿼리 캐시 총 블록 수

4. 쿼리 캐시를 켭니다.

MySQL의 쿼리 캐시는 기본적으로 꺼져 있습니다. 쿼리 캐시를 켜십시오. query_cache_type 이 매개변수에는 세 가지 가능한 값이 있습니다:

캐싱하지 않습니다. 요청 시 수행됩니다. SQL_CACHE를 명시적으로 지정하는 SELECT 문만 캐시됩니다. 다른 것들은 캐시되지 않습니다
의미
OFF 또는 0 쿼리 캐시 기능이 꺼짐
ON 또는 1 쿼리 캐시 SELECT 결과가 캐싱 조건을 만족하면 캐싱되지 않습니다. 명시적으로 SQL_NO_CACHE를 지정하거나 2

如何设置query_cache_type的值呢,这里我们需要修改MySQL的配置文件
博主的Ubuntu(Linux操作系统)版本为16.04,mysql版本为5.7。需要进入到/etc/mysql/mysql.conf.d下修改配置文件mysqld.cnf
MySQL 쿼리 캐시 최적화에 대한 고급 설명
添加以下内容
MySQL 쿼리 캐시 최적화에 대한 고급 설명
然后需要重启MySQL服务

再登录MySQL
MySQL 쿼리 캐시 최적화에 대한 고급 설명
此时可再查询MySQL查询缓存是否开启
MySQL 쿼리 캐시 최적화에 대한 고급 설명

配置完毕之后,重启服务既可生效 ;

然后就可以在命令行执行SQL语句进行验证 ,执行一条比较耗时的SQL语句,然后再多执行几次,查看后面几次的执行时间;获取通过查看查询缓存的缓存命中数,来判定是否走查询缓存。

我们可以进行测试,我们曾经建了一张表tb_item,里面有250万条数据。

mysql> select count(*) from tb_item;+----------+| count(*) |+----------+|  2499695 |+----------+1 row in set (8.57 sec)mysql> select count(*) from tb_item;+----------+| count(*) |+----------+|  2499695 |+----------+1 row in set (0.00 sec)

可以看到,第一次执行8s,第二次执行相同的SQL语句,只需要0s
这样我们就验证了查询缓存确实开启并且生效了。
我们可以看到缓存状态,命中数有了1次,添加到缓存中的次数为1次(因为相同的SQL语句只在第1次查询的时候添加)
MySQL 쿼리 캐시 최적화에 대한 고급 설명

5、查询缓存SELECT选项

可以在SELECT语句中指定两个与查询缓存相关的选项 :
SQL_CACHE : 如果查询结果是可缓存的,并且 query_cache_type 系统变量的值为ON或 DEMAND ,则缓存查询结果 。
SQL_NO_CACHE : 服务器不使用查询缓存。它既不检查查询缓存,也不检查结果是否已缓存,也不缓存查询结果。

注意:当 query_cache_type 系统变量的值为ON时,即使不加SQL_CACHE,也是会缓存的,而query_cache_type的变量的值为DEMAND,只有显示的指定了SQL_CACHE,才会做缓存。

tb_item表的前两行信息如下

mysql> select * from tb_item limit 2;+----+------------+----------+-------+------------+--------+------------+---------------------+---------------------+| id | title      | price    | num   | categoryid | status | sellerid   | createtime          | updatetime          |+----+------------+----------+-------+------------+--------+------------+---------------------+---------------------+|  1 | 货物1号    | 33494.85 |   365 |          0 | 1      | 5435343235 | 2019-04-20 22:37:15 | 2019-04-20 22:37:15 ||  2 | 货物2号    |  5617.72 | 24060 |          0 | 1      | 5435343235 | 2019-04-20 22:37:15 | 2019-04-20 22:37:15 |+----+------------+----------+-------+------------+--------+------------+---------------------+---------------------+2 rows in set (0.04 sec)

我们测试查询(注意,上一条语句已经被放到缓存中,相应的状态值会发生改变)

mysql> select title,sellerid from tb_item where id=1;+------------+------------+| title      | sellerid   |+------------+------------+| 货物1号    | 5435343235 |+------------+------------+1 row in set (0.00 sec)mysql> show status like 'Qcache%';+-------------------------+----------+| Variable_name           | Value    |+-------------------------+----------+| Qcache_free_blocks      | 1        || Qcache_free_memory      | 16764840 || Qcache_hits             | 1        || Qcache_inserts          | 3        || Qcache_lowmem_prunes    | 0        || Qcache_not_cached       | 3        || Qcache_queries_in_cache | 3        || Qcache_total_blocks     | 8        |+-------------------------+----------+8 rows in set (0.00 sec)

说明这一条语句也被加入到缓存中

当我不想要做缓存的时候,我们需要在select后面加上SELECT_NO_CACHE

mysql> select SQL_NO_CACHE title,sellerid from tb_item where id=2;+------------+------------+| title      | sellerid   |+------------+------------+| 货物2号    | 5435343235 |+------------+------------+1 row in set, 1 warning (0.00 sec)mysql> show status like 'Qcache%';+-------------------------+----------+| Variable_name           | Value    |+-------------------------+----------+| Qcache_free_blocks      | 1        || Qcache_free_memory      | 16764840 || Qcache_hits             | 1        || Qcache_inserts          | 3        || Qcache_lowmem_prunes    | 0        || Qcache_not_cached       | 4        || Qcache_queries_in_cache | 3        || Qcache_total_blocks     | 8        |+-------------------------+----------+8 rows in set (0.03 sec)

Qcache_inserts 的值仍然为3,说明没有缓存进去。

6、查询缓存失效的情况

我们前面已经提高过,当query_cache_type的值设置为1的时候,它会缓存符合条件的select语句的结果。原因是因为在某些情况下,查询缓存是会失效的。

1) SQL 语句不一致的情况, 要想命中查询缓存,查询的SQL语句必须完全一致。

SQL1 : select count(*) from tb_item;SQL2 : Select count(*) from tb_item;

仅大小写不同。

mysql> select count(*) from tb_item;+----------+| count(*) |+----------+|  2499695 |+----------+1 row in set (0.00 sec)mysql> Select count(*) from tb_item;+----------+| count(*) |+----------+|  2499695 |+----------+1 row in set (2.02 sec)

2) 当查询语句中有一些不确定的时,则不会缓存。如 : now() , current_date() , curdate() , curtime() , rand() , uuid() , user() , database() 。这些函数每次获取的结果都不同。

SQL1 : select * from tb_item where updatetime <p><strong>3) 不使用任何表查询语句。</strong><br> 比如select一个常量select ‘hello’;</p><pre class="brush:php;toolbar:false">select 'A';

4) 查询 mysql, information_schema或 performance_schema 系统数据库中的表时,不会走查询缓存。
MySQL系统数据库包括mysql, information_schema或 performance_schema

select * from information_schema.engines;

5) 在存储的函数,触发器或事件的主体内执行的查询。

6) 如果表更改,则使用该表的所有高速缓存查询都将变为无效并从高速缓存中删除。这包括使用MERGE映射到已更改表的表的查询。一个表可以被许多类型的语句,如被改变 INSERT, UPDATE, DELETE, TRUNCATE TABLE, ALTER TABLE, DROP TABLE,或 DROP DATABASE 。

mysql> Select count(*) from tb_item;+----------+| count(*) |+----------+|  2499695 |+----------+1 row in set (0.00 sec)mysql> update tb_item set title='test1' where id=5;Query OK, 1 row affected (0.05 sec)Rows matched: 1  Changed: 1  Warnings: 0

mysql> Select count(*) from tb_item;+----------+| count(*) |+----------+|  2499695 |+----------+1 row in set (1.23 sec)mysql> Select count(*) from tb_item;+----------+| count(*) |+----------+|  2499695 |+----------+1 row in set (0.00 sec)

相关免费学习推荐:mysql数据库(视频)

위 내용은 MySQL 쿼리 캐시 최적화에 대한 고급 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제