MySQL 提供了查询缓冲的功能(只能在MySQL4.0.1及以上版本使用查询缓冲),我们可以通过查询缓冲在一定程度上提高查询性能。通过在MySQL安装目录中的my.ini文件设置查询缓冲。设置也非常简单,只需要将query_cache_type设为1即可。在设置了这个属性后,MySQL在执行任何SELECT语句之前,都会在它的缓冲区中查询是否在相同的SELECT语句被执行过,如果有,并且执行结果没有过期,那么就直接取查询结果返回。
但在写SQL语句时注意,MySQL的查询缓冲是区分大小写的。如下列的两条SELECT语句:
SELECT * from TABLE1; SELECT * FROM TABLE1;上面的两条SQL语句对于查询缓冲是完全不同的SELECT,而且查询缓冲并不自动处理空格,因此,在写SQL语句时,应尽量减少空格的使用,尤其是在SQL首和尾的空格(因为,查询缓冲并不自动截取首尾空格)。
$ mysql.admin ext -i 1 | grep "Qcache_hits" | Qcache_hits | 0 | $ mysql.admin ext -i 1 | grep "Qcache_queries_in_cache" | Qcache_queries_in_cache | 0 | /* 初始化数据: */ mysql> create table tb_qc(a int,b char(10)); Query OK, 0 rows affected (0.00 sec) mysql> insert into tb_qc values(1,'line1'); Query OK, 1 row affected (0.00 sec) mysql> insert into tb_qc values(2,'line2'); Query OK, 1 row affected (0.00 sec) /* 查看状态值: */ $ mysql.admin ext -i 1 | grep "Qcache_hits" | Qcache_hits | 0 | $ mysql.admin ext -i 1 | grep "Qcache_queries_in_cache" | Qcache_queries_in_cache | 0 | /* 此时,Qcache_hits=0,Qcache_queries_in_cache=0,没有变化,执行一个查询:*/ mysql> select * from tb_qc where a=1; +------+-------+ | a | b | +------+-------+ | 1 | line1 | +------+-------+ 1 row in set (0.00 sec) /* 查看状态值: */ $ mysql.admin ext -i 1 | grep "Qcache_hits" | Qcache_hits | 0 | $ mysql.admin ext -i 1 | grep "Qcache_queries_in_cache" | Qcache_queries_in_cache | 1 | /* Qcache_hits=0,没有命中query cache里任何sql(此时qc里面也没有sql); Qcache_queries_in_cache=1,执行过一次后sql就存储在qc里面 再执行一次相同的sql,应该可以直接从qc里面取得结果数据,试一下 */ mysql> select * from tb_qc where a=1; $ mysql.admin ext -i 1 | grep "Qcache_hits" | Qcache_hits | 1 | $ mysql.admin ext -i 1 | grep "Qcache_queries_in_cache" | Qcache_queries_in_cache | 1 | /* Qcache_hits=1,说明确实命中了qc中的sql */ /* 再执行一个不同条件的 */ mysql> select * from tb_qc where a=2; +------+--------+ | a | b | +------+--------+ | 2 | line2 | +------+--------+ 1 row in set (0.00 sec) $ mysql8801.admin ext -i 1 | grep "Qcache_hits" | Qcache_hits | 1 | $ mysql8801.admin ext -i 1 | grep "Qcache_queries_in_cache" | Qcache_queries_in_cache | 2 | /*Qcache_hits=1,没有命中,因为qc里面只有a=1的sql,没有a=2的; 但Qcache_queries_in_cache=2,说明新的sql也被cache了,下次执行就可以直接从qc取结果了 */
SELECT SQL_NO_CACHE field1, field2 FROM TABLE1;以上的SQL语句由于使用了SQL_NO_CACHE,因此,不管这条SQL语句是否被执行过,服务器都不会在缓冲区中查找,每次都会执行它。
SELECT SQL_CALHE * FROM TABLE1;此外,官方文档中说,qc里的表不能有任何变动(Insert/Update/Delete/Replace/select .. for update/load data infile/Alter table/Truncate/Drop table/Drop database),否则qc里面的数据就无效,会被清掉。
/*新增一行数据: */ mysql> insert into tab_qc values(3,'SINA'); Query OK, 1 row affected (0.00 sec) $ mysql8801.admin ext -i 1|grep "Qcache_hits" | Qcache_hits | 1 | $ mysql8801.admin ext -i 1|grep "Qcache_queries_in_cache" | Qcache_queries_in_cache | 0 | /* Qcache_queries_in_cache=0,说明qc里面之前缓存的sql结果已经被清掉了,尽管我做的修改与qc里的数据无关*/如果是这样,那QC的使用场景就十分有限了,查询多,但对表的更改很少才能体现出QC的价值。哪怕是一行数据的修改都会导致数据从QC从中清除。