MySQL缓存机制详解
众所周知,缓存的设置是所有现代计算机系统发挥高性能的重要因素之一。对于MySQL数据库来说,也是得益于MySQL缓存机制,才能够提高MySQL数据库的性能,减少数据的内存占比。
MySQL缓存机制简单的说就是缓存SQL文本及查询结果,如果运行相同的SQL,服务器直接从缓存中取到结果,而不需要再去解析和执行SQL。如果表更改了,那么使用这个表的所有缓存查询将不再有效,查询缓存中值相关条目被清空。这里的更改指的是表中任何数据或是结构发生改变,包括INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE等,也包括那些映射到改变了的表使用MERGE表的查询。显然,这对于频繁更新的表,查询缓存是不适合的,而对于一些不常改变数据且有大量相同SQL查询的表,查询缓存会节约很大的性能。
一、MySQL缓存规则
1.开启了缓存,MySQL Server会自动将查询语句和结果集返回到内存,下次再查直接从内存中取;
2.缓存的结果是通过sessions共享的,所以一个client查询的缓存结果,另一个client也可以使用。
3.MySQL Query Cache内容为 select 的结果集, cache 使用完整的SQL字符串做 key, 并区分大小写,空格等。即两个SQL必须完全一致才会导致cache命中。即检查查询缓存时,MySQL Server不会对SQL做任何处理,它精确的使用客户端传来的查询,只要字符大小写或注释有点不同,查询缓存就认为是不同的查询;
4.prepared statement永远不会cache到结果,即使参数完全一样。在 5.1 之后会得到改善。
5.where条件中如包含任何一个不确定的函数将永远不会被cache, 比如current_date, now等。
6.date 之类的函数如果返回是以小时或天级别的,最好先算出来再传进去。
select * from foo where date1=current_date -- 不会被 cache
select * from foo where date1='2008-12-30' -- 被cache, 正确的做法
7.太大的result set不会被cache (< query_cache_limit)
8.MySQL缓存在分库分表环境下是不起作用的
9.执行SQL里有触发器,自定义函数时,MySQL缓存也是不起作用的
二、缓存失效
在表的结构或数据发生改变时,查询缓存中的数据不再有效。如INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE会导致缓存数据失效。所以查询缓存适合有大量相同查询的应用,不适合有大量数据更新的应用。
一旦表数据进行任何一行的修改,基于该表相关cache立即全部失效。
- 手动清理缓存
手动清理缓存可以使用下面三个SQL
1.FLUSH QUERY CACHE; #清理查询缓存内存碎片
2.RESET QUERY CACHE;#从查询缓存中移除所有查询
3.FLUSH TABLES; #关闭所有打开的表,同时该操作会清空查询缓存中的内容
四、缓存机制中的内存管理
MySQL Query Cache 使用内存池技术,自己管理内存释放和分配,而不是通过操作系统。内存池使用的基本单位是变长的block, 用来存储类型、大小、数据等信息;一个result set的cache通过链表把这些block串起来。block最短长度为query_cache_min_res_unit。
当服务器启动的时候,会初始化缓存需要的内存,是一个完整的空闲块。当查询结果需要缓存的时候,先从空闲块中申请一个数据块为参数query_cache_min_res_unit配置的空间,即使缓存数据很小,申请数据块也是这个,因为查询开始返回结果的时候就分配空间,此时无法预知结果多大。
分配内存块需要先锁住空间块,所以操作很慢,MySQL会尽量避免这个操作,选择尽可能小的内存块,如果不够,继续申请,如果存储完时有空余则释放多余的。
但是如果并发的操作,余下的需要回收的空间很小,小于query_cache_min_res_unit,不能再次被使用,就会产生碎片。
MySQL缓存机制从某种程度上来说,和其他的系统缓存有类似的作用:提高系统的性能,释放系统的内存空间。但MySQL缓存机制又有着其独特的特性,对于数据重复性比较高的查询有着显著的作用。
原文地址:https://www.cnblogs.com/cqqfboy/p/15175186.html
- 自定义圆形控件RoundImageView并认识一下attr.xml
- 自定义带图片和文字的ImageTextButton
- 超值干货:个人开发者如何使用免费又简单的开发后台
- 【周末分享】解决中文排版错位的JustifiedTextview控件
- 超级网络
- c++ fstream + string 处理大数据
- 超炫的FlowingDrawer效果
- 源码分享:仿余额宝数字跳动效果 TextCounter
- 一键清理应用数据或者清除应用缓存的方法
- 开发者必知:谷歌做了一个艰难的决定
- React编程思想
- 基于 React + Webpack 的音乐相册项目(下)
- Python中Keras深度学习库的回归教程
- Apache Spark 1.1中的统计功能
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解
- Python | 详解Python中的协程,为什么说它的底层是生成器?
- 初识Mybatis中的动态sql
- Raw use of parameterized class 'Future'
- javaweb遇到的报错问题以及解决方案(持续更新)
- Spark Java UDAF 输入struct嵌套结构
- 深入理解Java内存模型
- Mybatis高级查询(一):resultMap与resultType
- JDK错误用法—TimSort
- Mybatis高级查询(三):分页查询
- 以OpenResty搭建RTB竞价引擎接入层
- 优化Linux bootloader速度的究极之路:从GRUB到EFI Stub
- Linux--nc命令
- Netty之美--I/O模型
- 023.基于IT论坛案例学习Elasticsearch(二):Query高级知识(一)
- 打卡群刷题总结0807——验证二叉搜索树