顾名思义,QueryCache就是查询缓存,是一个很大的Hash表,存放的是select的文本的hash值和查询结果。当下一次相同的select语句再次去查询数据时,可以直接到QueryCache里检查,如果发现有相同的sql(sql文本hash值相同),则结果直接在QueryCache,省去了Parse,explain等过程。而且QueryCache是针对全局来说的,就是说在所有session之间是可以共享的。对于那些不经常变更的表,而且相同查询比较多的sql比较适合使用QueryCache。总结如下几点:
1.QueryCache是全局共享的,所有session共有。
2.QueryCache适用于不经常变更的表,如果表结构或者数据经常变更,在变更的同时不仅要lock住该QueryCache,导致争用。同时还会invalidate该数据,下次查询,QueryCache反而多了一次检查。
3.在Mysql 5.1.17以前,在使用了ODBC/JDBC的PrepareStatement的操作中是不能使用该QueryCache的,在5.1.17之后才可以继续使用。
4.QueryCache对大小写敏感,对于大小写不同,中间空格不同的sql文本,QC会生成不同的hash值,所以sql文本应该严格一致。
5.QC对database,协议,版本,默认字符集等不同,也会认为是不同的query,从而分别存储。
对于QueryCache工作流程,Percona的一幅图有非常清晰的说明:
当然,如果是sql在QC里面命中的话,可能情况如下图:
使用QC之后带来的开销
1.多了一次到QC检查的过程。
2.能够cache但是还没有cache到QC,会多一次cache到QC的过程。
3.每次update/insert/delete/ddl..etc都会检查QC,并将有关联相关表的信息invalidate。
可能带来的QC无效的原因
1.sql的大小写可能不一致,或者使用的数据库,字符集等环境不一致。
2.sql中包含临时表,用户变量,now(),rand()等不确定的函数。
3.column设置了权限,或者查询中使用了lock in share mode/for update。
4.用户自定义函数。
QC涉及的主要参数:
query_cache_size : 0表示禁用queryCache,默认情况下是0.设置该值要小心,在更新相关的表期间,thread会lock住QC,设置的太大可能会导致lock contention ,该值最小至少有40kb,而且是1024 byte的整数倍。
query_cache_type:0/OFF表示禁用QC。1表示开启QC,1/ON表示开启QC,但是对以select sql_no_cache开始的sql无效。2/demand只cache那些以select sql_cache开始的sql.
query_cache_limit:针对每个sql所能使用的cache的最大值,默认是1MB.注意:也可以在运行时设置--maxmum-query_query_cache的值来控制sql所能使用的cache的最大值。
query_cache_min_res_unit:mysql每次分配cache的最小单元block。
阅读(1703) | 评论(0) | 转发(0) |