在mysql服务器高负载的情况下,必须采取一种措施给服务器减轻压力,减少服务器的I/O操作。一般采用的方法是优化sql操作语句,优化服务器的配置参数,从而提高服务器的性能。Mysql使用了几种内存缓存数据的策略来提高性能。
一、mysql的缓存机制
Mysql缓存主要包括关键字缓存(key cache)和查询缓存(query cache),这主要讲解mysql的查询缓存(query cache)机制。
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查询的表,查询缓存会节约很大的性能。
查询必须是完全相同的(逐字节相同)才能够被认为是相同的,字符的大小也被认为是不同的。另外,同样的查询字符由于其他原因可能认为是不同的。使用不同的数据库,不同的协议版本或者不同默认字符字符集的查询被认为是不同的查询并且分别进行缓存。
2.mysql查询缓存的工作原理
当mysql收到传入的sql语句时,它首先和先前已经解析过的sql语句进行比较,如果发现相同,则返回已缓存数据。一定是完全相同。下面两个是不同的:
01 SELECT 课程名 FROM KC;
02 select 课程名 from kc
因为大小写的缘故,两条sql语句被认为是不同的,他们的缓存是不能共享的。另外,如果一条sql语句是另外一条sql语句的子串,类似下面的情况,第02行的语句不会被缓存;如果sql语句是存储过程、触发器或者事件内部的一条语句,同样也不会被缓存。查询缓存也受到权限的影响,对于没有权限访问数据库中数据的用户,即使输入了同样的sql语句,缓存中的数据也会无权访问。
01 SELECT 课程名 FROM KC where 学分 in(
02 SELECT 学分 FROM KC
03 );
当传入的sql语句被认为是存在缓存的情况下,系统会修改mysql的一个状态变量Qcache_hits,并将其值增加1,可以运行语句来查看qcahce_hits的值,如下:
mysql> show status like '%qcache_hits%'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Qcache_hits | 0 | +---------------+-------+ 1 row in set (0.00 sec)
上述表中,Qcache为0,表示目前缓存的命中率为0,一旦缓存生效,该值大于1。例如,先输入如下的sql语句:
01 select * from kc;其值增加1
以下这些形式的查询不会缓存。
l Select ...... Lock in share mode
l Select ...... For update
l Select ...... Into outfile ...
l Select ...... Into dumpfile
l Select * from ... Where autoincrement_col is null
3.查看mysql的缓存信息
默认情况下mysql的查询缓存是被打开的,可以通过查询mysql的系统变量来查看mysqld是否支持缓存,输入下面命令:
mysql> show variables like 'have_query_cache'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | have_query_cache | YES | +------------------+-------+ 1 row in set (0.00 sec) mysql> show status like '%qcache_cache%'; Empty set (0.00 sec) mysql> show status like '%qcache%'; +-------------------------+-------+ | Variable_name | Value | +-------------------------+-------+ | Qcache_free_blocks | 0 | 缓存空闲的内存块 | Qcache_free_memory | 0 | 在query_cache_size设置的缓存中的空闲的内存 | Qcache_hits | 0 | 缓存的命中次数 | Qcache_inserts | 0 | 查询缓存区此前总共缓存过多少条查询命令的结果 | Qcache_lowmem_prunes | 0 | 查询缓存区已满而从其中溢出和删除的查询结果的个数 | Qcache_not_cached | 0 | | Qcache_queries_in_cache | 0 | | Qcache_total_blocks | 0 | 缓存总的内存块 +-------------------------+-------+ 8 rows in set (0.00 sec)
二、mysql查询缓存的配置和使用
1.配置查询缓存
查询缓存的配置可以通过设置系统环境变量来完成,设置环境变量一般有两种方式:一种是配置文件中配置;另外可以在命令行中配置。
Vim /etc/my.cnf
Query_cache_type可以是0,1,2,0代表不使用缓存,1代表使用缓存,2代表根据需要使用
2.使用查询缓存
3.查询缓存的维护
在使用查询缓存时,可以通过have_query_cache来查看当前服务器是否支持查询缓存,
mysql> show variables like 'have_query_cache'; +------------------+-------+ | Variable_name | Value | +------------------+-------+ | have_query_cache | YES | +------------------+-------+ Yes表示支持 当查询缓存工作一定时间后,通过show status来监控缓存的性能 mysql> show status like '%qcache%'; +-------------------------+-----------+ | Variable_name | Value | +-------------------------+-----------+ | Qcache_free_blocks | 1 | | Qcache_free_memory | 268414376 | | Qcache_hits | 0 | | Qcache_inserts | 2 | | Qcache_lowmem_prunes | 0 | | Qcache_not_cached | 3 | | Qcache_queries_in_cache | 2 | | Qcache_total_blocks | 7 | +-------------------------+-----------+ 查询缓存会生成碎片,可以通过下面命令来清理碎片 mysql> flush query cache; Query OK, 0 rows affected (0.00 sec) 如果想清理内存中的碎片: mysql> reset query cache; Query OK, 0 rows affected (0.00 sec) 两个命令同时使用,彻底清理碎片。