原文链接:http://www.ibearzmblog.com/#/technology/info?id=5770c555acd4302f81d86976c06e2319
前言
当我们向数据库服务器发送一条SQL的时候,但数据库收到后就会执行,但是如果在短时间内都执行同一条SQL,如果每次数据库都会执行,并且每次执行的结果都是一样,那就有点多余。
所以MySQL就会将查询的结果缓存起来,后面的相同查询将会直接返回结果。
这篇文章也是我查官方文档的一个笔记。
这是官方中文文档:https://www.mysqlzh.com/
简介
查询缓存存储SELECT查询的文本以及发送给客户端的相应结果。如果随后收到一个相同的查询,服务器从查询缓存中重新得到查询结果,而不再需要解析和执行查询。如果你有一个不经常改变的表并且服务器收到该表的大量相同查询,查询缓存在这样的应用环境中十分有用。对于许多Web服务器来说存在这种典型情况,它根据数据库内容生成大量的动态页面。 -----摘自官方文档
工作原理
当开启缓存后,SQL语句的解析会有所不同,比如会区分大小写:
select * from table_name
SELECT * FROM table_name
上面的两条SQL会被认为不同,查询SQL必须是每个字都一样的,同样,使用不同的数据库、字符集也会影响解析,一旦发现两条SQL不是完全一致,那么就会分别缓存。
缓存失效
那么缓存后的数据失效的情况也有几种。
表发变化
当表发生变化的时候,那么涉及到该表的所有缓存数据将会失效。例如我们常用的insert、delete、update、alter等等。
使用函数
使用下面函数的话,不会被放入缓存。我这里就直接从官网摘下来:
BENCHMARK() | CONNECTION_ID() | CURDATE() | CURRENT_DATE() |
CURRENT_TIME() | CURRENT_TIMESTAMP() | DATABASE() | NOW() |
带一个参数的ENCRYPT() | FOUND_ROWS() | GET_LOCK() | LAST_INSERT_ID() |
LOAD_FILE() | MASTER_POS_WAIT() | RAND() | RELEASE_LOCK() |
不带参数的UNIX_TIMESTAMP() | USER() |
其他条件
- 引用自定义函数
- 引用自定义变量
- 引用系统表
查询缓存
可以通过SQL语句来查询结果是否被缓存:
SQL_CACHE,如果查询结果中query_cache_type的值为ON或DEMAND,那么结果就为已缓存。
SELECT SQL_CACHE,id, name FROM user_info;
开启缓存
首先我们可以执行下面的语句查看缓存是否可用
SHOW VARIABLES LIKE 'have_query_cache';
可以看到,这里为YES,但这不意味着缓存已开启。
同时我们也可以通过query_cache_size来设置缓存大小,当设置为0的时候表示缓存禁用。同时,如果设置大于0的时候,查询缓存至少需要大于40KB来进行分配,设置少的话会得到警告信息,所以我们设置需要大于40KB。
我们先看看当前缓存大小设置是多少。
SHOW VARIABLES LIKE 'query_cache_size';
Value为0,那么说明当前缓存是被禁用的。
那么现在我们先将他改为1MB,然后再看看query_cache_size变量的值:
set @@global.query_cache_size=1000000;
SHOW VARIABLES LIKE 'query_cache_size';
可以看到,已经设置成功。
设置完query_cache_size的值后,query_cache_type变量为工作方式,主要有三种:
- 0或OFF将阻止缓存或查询缓存结果
- 1或ON将允许缓存,以SELECT SQL_NO_CACHE开始的查询语句除外
- 2或DEMAND,仅对以SELECT SQL_CACHE开始的那些查询语句启用缓存
query_cache_type设置的工作方式为后续客户端操作的缓存策略,所以需要好好设置。
结尾
MySQL的缓存设置在一定程度上减少磁盘IO的操作,也是一种提高性能的手段。