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

MYSQL-查询缓存

2019-05-08 22:53 627 查看

查询的执行路径

过程:

数据默认是放在磁盘上的文件,如果我们每次查询都要去磁盘上查找,效率是非常低下的。但是我们把查询过的数据放在缓存中,让内存代替磁盘来进行查询,那么效率是非常高的。

1、客户端通过与服务器之间的通信协议,微软的SQLserver有SQLserver的协议,Oracle有Oracle的协议,MySQL有MySQL的协议。
2、通过协议连接之后,客户端向服务器发送一个select的查询,如果服务器的缓存是打开的,那么服务器先去缓存空间中查找,如果有,则直接返回给用户。毫无疑问,这样的查询速度是最快的。
3、如果缓存空间没有,则服务器对客户发送的指令进行解析,请求的sql语句会生成一个解析树,通过语法分析,从左到右一个字符一个字符的输入,根据构词规则识别单词,识别sql语句中的关键字和非关键字,然后进行语法解析,判断这个SQL语句是否满足MySQL语法规则,如果语法不对,则会返回报错信息,提示用户报错
如果语法正确,则会检查解析的语句是否合法,如检查查询的表明,字段是否正确,是否有有对应的查询权限,然后生成新的解析树。
4、查询优化器会查询语句中是否有很好的查询方法,比如,索引。
5、如果有,则将SQL语句转换为执行计划,交给查询执行引擎,
6、查询执行引擎根据这个执行计划来完成整个查询。
7、调用API接口,连接到数据库,将要查询的数据从硬盘中读取出来
8、将查询的数据一份返回给客户端,一份存在缓存空间。
这样查询的整个过成就结束了

查询缓存

查询缓存( Query Cache )原理

查询缓存是通过hash来进行查询的
我们键入select指令的时候,系统会对这条语句进行hash运算,得到一串hash值,然后用这串hash值在缓存空间中寻找是否有同样的hash值,如果有,则返回给用户,如果没有,则执行查询工作

注意:
hash运算具有特殊性质:雪崩效应, 当你键入同样的SQL语句的时候,虽然两次键入的SQL语句返回的结果是相同的,但是,一旦多键入一个空格,或者其他字符,则生成的hash值则完全不一样,所以,它不会去缓存空间中寻找。

缓存SELECT操作或预处理查询的结果集和SQL语句,当有新的SELECT语句或预处理查询语句请求,先去查询缓存,判断是否存在可用的记录集,判断标准:与缓存的SQL语句,是否完全一样,区分大小写

优缺点

不需要对SQL语句做任何解析和执行,当然语法解析必须通过在先,直接从Query Cache中获得查询结果,提高查询性能
查询缓存的判断规则,不够智能,也即提高了查询缓存的使用门槛,降低其效率;
查询缓存的使用,会增加检查和清理Query Cache中记录集的开销

不会被缓存的数据

1、查询语句中加了SQL_NO_CACHE参数
2、查询语句中含有获得值的函数,包含自定义函数,如:
NOW()、CURDATE()、GET_LOCK()、RAND()、CONVERT_TZ()等
3、对系统数据库的查询:mysql、information_schema 查询语句中使用SESSION级别变量或存储过程中的局部变量
4、查询语句中使用了LOCK IN SHARE MODE、FOR UPDATE的语句,查询语句中类似SELECT …INTO 导出数据的语句
5、对临时表的查询操作;存在警告信息的查询语句;不涉及任何表或视图的查询语句;某用户只有列级别权限的查询语句
6、事务隔离级别为Serializable时,所有查询语句都不能缓存

查询缓存相关的服务器变量

show variables like 'query_cache%';  查询缓存变量

以下四个及时服务器变量也是服务器选项

query_cache_min_res_unit:

查询缓存中内存块的最小分配单位,默认4k,较小值会减少浪费,但会导致更频繁的内存分配操作,较大值会带来浪费,会导致碎片过多,内存不足

query_cache_limit:

单个查询结果能缓存的最大值,默认为1M,对于查询结果过大而无法缓存的语句,建议使用SQL_NO_CACHE

query_cache_size:

查询缓存总共可用的内存空间;单位字节,必须是1024的整数倍,最小值40KB,低于此值有警报

query_cache_wlock_invalidate:

如果某表被其它的会话锁定,是否仍然可以从查询缓存中返回结果,默认值为OFF,表示可以在表被其它会话锁定的场景中继续从缓存返回数据;ON则表示不允许

query_cache_type:

是否开启缓存功能,取值为ON, OFF, DEMAND

设置缓存变量

将query_cache_size设置为5M

需要注意的是,用SQL语句是只能以字节为单位

需要注意的是,用SQL语句是只能以字节为单位
写入配置文件可以使用M单位
set global query_cache_size=512000;
vim my.conf
query_cache_size=5M
重启服务即可

设置query_cache_type为启动

vim my.conf
query_cache_type=ON
重启服务即可

查看缓存状态

查询缓存相关的状态变量:SHOW GLOBAL STATUS LIKE ‘Qcache%';

Qcache_free_blocks:       处于空闲状态 Query Cache中内存 Block 数
Qcache_total_blocks:      Query Cache 中总Block ,当Qcache_free_blocks相对此值较大时,可能用内存碎片,执行FLUSH QUERY CACHE清理碎片
Qcache_free_memory:       处于空闲状态的 Query Cache 内存总量
Qcache_hits:              Query Cache 命中次数
Qcache_inserts:           向 Query Cache 中插入新的 Query Cache 的次数,即没有命中的次数
Qcache_lowmem_prunes:     记录因为内存不足而被移除出查询缓存的查询数
Qcache_not_cached:        没有被 Cache 的 SQL 数,包括无法被 Cache 的 SQL 以及由于 query_cache_type 设置的不会被 Cache 的 SQL语句
Qcache_queries_in_cache:  在 Query Cache 中的 SQL 数量
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: