查询缓存(Query Cache)是MySQL Server层提供的一种缓存机制。如果执行相同的一个SQL语句,MySQL数据库会将数据缓存起来以供下次直接使用。使用查询缓存可以减少IO操作,降低服务器压力。如何查看是否开启查询缓存,命令如下:
SHOW VARIABLES LIKE 'query_cache_type';
其结果值如下所示
OFF(0): 禁用查询缓存。
ON(1): 启用查询缓存。
DEMAND(2): 只有使用 SQL_CACHE 关键字的查询才会使用缓存。
MySQL的查询缓存默认是关闭的,需要手动配置参数query_cache_type来开启查询缓存。修改配置文件:linux的是/etc/my.conf,Windows的是my.ini 文件,在mysqld组下面增加:
query_cache_type=1
query_cache_size=128M
重启Mysql后进行查询
SHOW VARIABLES LIKE 'query_cache_type';
SHOW VARIABLES LIKE 'query_cache_size';
前者显示“ON”,后者显示“134217728”字节(就是128M大小)。
如果设置query_cache_size 设置为 0 时,也表示禁用查询缓存了。
开启查询缓存后,输入如下命令查询全局缓存状态:
SHOW GLOBAL STATUS LIKE '%Qcache%';
Qcache_free_blocks:缓存池中空闲块的个数
Qcache_free_memory:缓存中空闲内存量
Qcache_hits:缓存命中次数
Qcache_inserts:缓存写入次数
Qcache_lowmen_prunes:因内存不足删除缓存次数
Qcache_not_cached:查询未被缓存次数
Qcache_queries_in_cache:当前缓存中缓存的SQL数量
Qcache_total_blocks:缓存总block数
以上参数中的“Qcache_hits” 缓存命中次数将决定我们的缓存利用率的问题。如果我们开启了查询缓存,并且设置了较大缓存空间,但是缓存命中次数很低,说明我们的查询缓存没有起到效果。这里提醒大家的是,对表的任何DML操作都会导致缓存情况,包括insert,update,delete,truncate,alter table,drop table等等。也就是说,只要有对一个表的更新,这个表上的所有的查询缓存都会被清空。因此很可能你费劲地把结果缓存起来,还没使用呢,就被一个更新全清空了。对于更新频繁的数据库来说,查询缓存的命中率会非常低。因此读写非常频繁的业务场景,缓存开启还不如关闭效率高。在MySQL8.0及以上版本,MySQL的查询缓存功能已经被删除了。
MySQL的查询缓存一旦开启,会将所有SQL语句的结果集全部放入缓存中,如果我们想指定哪些SQL语句存入缓存或者不缓存的话,可以使用以下关键字:
SQL_CACHE:如果查询结果是可缓存的,并且 query_cache_type 系统变量的值为 ON 或 DEMAND ,则缓存查询结果
SQL_NO_CACHE:服务器不使用查询缓存。它既不检查查询缓存,也不检查结果是否已缓存,也不缓存查询结果。
对于 lnnoDB 数据库, MySQL 采用缓冲池(Buffer Pool)的方式来缓存数据和索引。Buffer Pool 的大小可以直接影响到数据库的性能表现,因为它决定了有多少数据可以直接从内存中读取,而无需访问磁盘。innodb_buffer_pool_size 参数决定了 Buffer Pool 的大小,通常应配置为物理内存的 60% ~ 80% 左右,以确保 MySQL 可以将更多的热数据保存在内存中。
查看 Buffer Pool 大小
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
默认值为128M,我们设置 Buffer Pool 为 2GB
SET GLOBAL innodb_buffer_pool_size = 2G;
最好还是修改配置文件内容如下:
[mysqld]
innodb_buffer_pool_size = 2048M
总结,一般情况下,我们都不会倾向于使用Mysql的缓存功能来提升查询性能。我们都是采用比较成熟的软件来进行缓存,如redis、memcache等等。原因有两个,第一他们是内存级别的,读取速度快;第二缓存数据可控,我们可以根据业务需求去缓存和更新他们。