您的位置:首页 > 数据库 > MySQL

第 16 章 MySQL缓存的配置和使用

2017-05-26 10:41 351 查看
在MySQL服务器高负载的情况下,必须采取一种措施给服务器减轻压力,减少服务器的IO操作。一般采用的方法是优化SQL操作语句,优化服务器的配置参数,从而提高服务器的性能。MySQL使用了几种内存缓存数据的策略来提高性能。对于使用和管理MySQL的人员来说,了解并掌握MySQL数据库的缓存机制和MySQL是如何利用内存来提升数据高频率的存取性能,是很重要的一个方面。

16.1 MySQL的缓存机制

MySQL缓存主要包括关键字缓存(Key Cache)和查询缓存(Query Cache),本节主要讲解MySQL的查询缓存机制。

16.1 查询缓存概述

在MySQL的性能优化方面经常涉及到缓存区(Buffer)和缓存(Cache),MySQL通过在内存中建立缓存区(Buffer)和缓存(Cache)来提升MySQL的性能。对于InnoDB数据库,MySQL采用缓存池(Buffer Pool)的方式来缓存数据和索引;对于MylSAM数据库,MySQL采用缓存的方式来缓存数据和索引。

MySQL查询缓存机制(Query Cache)简单地说就是缓存SQL语句及查询结果,如果运行相同的SQL,服务器直接从缓冲中取到结果,而不需要再去解析和执行SQL。而且这些缓存能被所有的会话共享,一旦某个客户端建立了查询缓存,其他发送同样SQL语句的客户端也可以使用这些缓存。

如果表更改了,那么使用这个表的所有缓存查询将不在有效,查询缓存值的相关条目被清空。更改指的是表中任何数据或是结构的改变,包括INSERT、UPDATE、DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE等。也包括那些映射到改变了的表的使用MERGE表的查询。显然,这对于频繁更新的表,查询缓存是不适合的,而对于一些不常改变数据且有大量相同SQL查询的表,查询缓存会节约很大的性能。

查询必须是完全相同的(逐字节)才能够被认为是相同的,字符的大小写也被认为是不同的。另外,同样的查询字符串由于其他原因可能认为是不同的。使用不同的数据库、不同的协议版本或者不用默认字符集的查询被认为是不同的查询并且分别进行缓存。

注意:在多个mysqld服务器更新相同的MyISAM表时,查询缓存是不会生效的。

16.1.2 MySQL查询缓存的工作原理

当MySQL收到传入的SQL语句时,它首先和之前已经解析过的SQL语句进行比对,如果发现相同,则返回已缓存数据。前面已经讲过,这里的相同一定是完全线相同,而且是逐字节相同。

另外,如果一条SQL语句是另外一条SQL语句的子串,或者SQL语句是存储过程、触发器或者事件内部的一条语句,都不会缓存。查询缓存也受到权限的影响,对于没有权限访问数据中数据的用户,即使输入了同样的SQL语句,缓存中的数据也是无权访问的。

当传入的SQL语句被认为是存在缓存的情况下,系统会修改MySQL的一个状态变量Qcache_hits,并将其值增加1,可以运行语句来查看Qcache_hits的值。

show STATUS LIKE ‘%qcache_hits%’;

由于InnoDB类型的表是支持事务操作的,当使用InnoDB类型的表时,包含在事务中的查询缓存也是会工作的。从MySQL 5.6之后,包含在视图中的查询结果也是会被缓存的。

查询缓存不会存储有不确定结果的查询。因此,任何一个包含不确定函数(NOW()或CURRENT()等)的查询结果不会被缓存。事实上,查询缓存不会缓存引用了用户自定义函数、存储函数、用户自定义变量、临时表、MySQL数据库中的表、INFORMATIN_SCHEMA数据库中的表、performance_schema数据库中的表或者任何一个有列级权限的表的查询。另外,如果在事务中使用了序列化隔离级别的表达式也是不能被缓存的。

16.1.3 查看MySQL的缓存信息

默认情况下MySQL的查询缓存是被打开的,可以通过查询MySQL中的系统变量mysqld是否支持缓存,输入下面的语句来查看查询缓存的支持与否。

show variables LIKE ‘have_query_cache’;

当然也可使用SELECT @@have_query_cache;来查看缓存是否支持。

输入下面的语句:

show variables like ‘%query_cache%’;

显示结果解释:

Have_query_cache显示YES表示支持查询缓存

query_cache_limit可缓存的最大结果集(字节数)大于此值的结果集不会被缓存,如果结果集大于此值,则MySQL增加Qcache_not_cached状态值。

query_cache_min_res_unit是为了避免Qcache碎片,需要平衡query_cache_min_res_unit大小和服务器保存查询结果时分配的块的数量,如果此值较小,那么会节省节省内存,但是这会使系统频繁分配内存块(占有CPU),若体积过大,则会造成造成较多的内存碎片(占有内存)。

query_cache_size显示查询缓存的大小,因为查询缓存本身的数据结构要占用大约40KB(不同系统会有差异),因此其值要大于40KB。

query_cache_type表示是否启用缓存。

query_cache_wlock_invalidate是否允许在其他连接处于lock状态时,使用缓存结果,默认为off。

输入下面的语句:

show STATUS LIKE ‘%qcache%’;

显示结果注释:

Qcache_free_blocks缓存空闲的内存块。

Qcache_free_memory在query_cache_size设置的缓存中的空闲的内存。

Qcache_hits前面已经讲过,表示缓存的命中的次数。

Qcache_inserts表示查询缓存区此前总共缓存过多少条查询命令的结果。

Qcache_lowmen_prunes表示查询缓存区已满而从其中溢出和删除的查询结果的个数。

Qcache_not_cached见上文的query_cache_limit,表示没有进入查询缓存区的查询命令个数。

Qcache_queries_in_cache查询缓存区当前缓存着多少条查询命令的结果。

Qcache_total_blocks表示缓存总的内存块。

16.2 MySQL查询缓存的配置和使用

本节主要讲解如何配置MySQL查询缓存的参数,如果维护和使用查询缓存。

16.2.1 配置查询缓存

查询缓存的配置可以通过设置系统环境变量来完成,设置环境变量一般有两种方式:一种是在配置文件中设置;第二种是在命令行中设置。

选项文件的配置

在Windows中MySQL的选项文件一般保存在下面几个位置。

(1)Windows安装目录下my.ini,通常windows安装目录为C:\windows,可以通过查看环境变量WINDIR来获取Windows安装目录,语句如下:

echo %windir%;(win命令)

(2)C:\my.cnf

(3)INSTALLDIR\my.ini,INSTALLDIR表示MySQL的安装目录

在UNIX系统中,选项文件一般保存到下面几个位置:

(1)/etc/my.cnf

(2)$mysql_home/my.cnf

(3)~/.my.cnf

命令行的设置

通过命令行来调整系统的参数更加灵活,大多数情况下采用SET命令。通过show variables 命令可以查看系统变量:show variables like ‘%cache%’;

通过SET命令可以设置全局系统变量和会话系统变量。

例:set global query_cache_size=5000;

set session query_cache_size=5000;

取消当前用户会话的缓存,语句如下:

set session query_cache_type=off;

如果有大量返回小结果数据的查询,默认数据块大小可能会导致内存碎片,显示为大量空闲内存块。由于缺少内存,内存碎片会强制查询缓存并从缓存内存中修整(删除)查询。这时,应该减少query_cache_min_res_unit变量的值。空闲快和由于内存调整而移除的查询的数量通过Qcache_free_blocks和Qcache_lowmen_prunes变量的值体现出来。

16.2.2 使用查询缓存

如果query_cache_type设置的是ON(1)或者DEMAND(2),那么用户在进行查询的时候,服务器会自动缓存查询结果。

在查询的时候有两个查询选项可以使用,分别是SQL_CACHE和SQL_NO_CACHE。其中,SQL_CACHE选项表示使用查询缓存,SQL_NO_CACHE表示不适用查询缓存。实例如下:

SELECT SQL_CACEH 课程名 FROM KC;

SELECT SQL_NO_CACHE 课程名 FROM KC;

第一句表示使用查询结果缓存,第二句表示不使用查询结果缓存。

16.2.3 查询缓存的维护

在使用MySQL数据库的时候,可以通过have_query_cache来查看当前的服务器是否支持查询缓存,这些在上面已经讲过,如果其值是YES,就表示查询缓存时生效的。如下:show variables like ‘have_query_cache’;

当查询缓存工作一定时间后,通过SHOW STATUS来监控缓存的性能使用方法如下:show status like ‘%qcache%’;

查询缓存的长时间工作可能会产生内存碎片,这时候,可以通过FLUSH QUERY CACHE语句来清理查询缓存碎片,执行该语句后,系统只会清除缓存碎片,并不会清除缓存的查询结果,这样就可以继续使用查询缓存,提高内存使用性能。如果想要从内存清除查询结果的缓存,就可以利用RESET QUERY CACHE语句和FLUSH TABLES语句来完成这样的工作

16.3 高手点拨

MySQL的查询缓存在一定程度上提高了系统的性能,在实际应用中,需要根据实际的情况多实践多总结。

查询缓存可以明显地改善性能,但是在使用缓存时还要注意以下两点。

(1)当缓冲非常大的时候,为了维持缓存的开销,服务器的性能会下降。一般情况下,缓存维持在几十MB,缓存的性能不错,一旦缓存达到几百NB,性能未必有所提升,甚至会下降。

(2)使用缓冲的服务器性能会有很明显的改善,但是如果在某个表上经常出现更新操作,甚至会把查询和更新操作一起使用的话,缓存的性能就会下降,这时候可以关闭查询缓存来减少服务器的开销。

如果查询缓冲还不能满足查询需要的性能,这时候可以优化SQL语句,或者对MySQL的库结构等实施优化,必要时可以采用Memcached、Redis等内存缓存数据库来解决性能问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息