对MySql查询缓存及SQL Server过程缓存的理解及总结

一、MySql的Query Cache

1、Query Cache   MySQL Query Cache是用来缓存我们所执行的SELECT语句以及该语句的结果集。MySql在实现Query Cache的具体技术细节上类似典型的KV存储,就是将SELECT语句和该查询语句的结果集做了一个HASH映射并保存在一定的内存区域中。当客户端发起SQL查询时,Query Cache的查找逻辑是,先对SQL进行相应的权限验证,接着就通过Query Cache来查找结果。它不需要经过Optimizer模块进行执行计划的分析优化,更不需要发生同任何存储引擎的交互,减少了大量的磁盘IO和CPU运算,所以有时候效率非常高。

2、Query Cache设置参数   可以通过调整 MySQL的参数打开并设置它的Query Cache功能,主要有以下5个参数:

  (1)、query_cache_limit:允许缓存的单条查询结果集的最大容量,默认是1MB,超过此参数设置的查询结果集将不会被缓存;

  (2)、query_cache_min_res_unit:设置查询缓存Query Cache每次分配内存的最小空间大小,即每个查询的缓存最小占用的内存空间大小;

  (3)、query_cache_size:设置 Query Cache 所使用的内存大小,默认值为0,大小必须是1024的整数倍,如果不是整数倍,MySQL 会自动调整降低最小量以达到1024的倍数;

  (4)、query_cache_type:控制 Query Cache 功能的开关,可以设置为0、1、2三种,意义分别如下:   a、0(OFF):关闭 Query Cache 功能,任何情况下都不会使用 Query Cache;   b、1(ON):开启 Query Cache 功能,但是当SELECT语句中使用SQL_NO_CACHE提示后,将不使用Query Cache;   c、2(DEMAND):开启Query Cache 功能,但是只有当SELECT语句中使用了SQL_CACHE 提示后,才使用Query Cache。

  (5)、query_cache_wlock_invalidate:控制当有写锁定发生在表上的时刻是否先失效该表相关的Query Cache,如果设置为 1(TRUE),则在写锁定的同时将失效该表相关的所有Query Cache,如果设置为0(FALSE)则在锁定时刻仍然允许读取该表相关的Query Cache。   3、Query Cache和性能   任何事情过犹不及,尤其对于某些写频繁的系统,开启Query Cache功能可能并不能让系统性能有提升,有时反而会有下降。原因是MySql为了保证Query Cache缓存的内容和实际数据绝对一致,当某个数据表发生了更新、删除及插入操作,MySql都会强制使所有引用到该表的查询SQL的Query Cache失效。对于密集写操作,启用查询缓存后很可能造成频繁的缓存失效,间接引发内存激增及CPU飙升,对已经非常忙碌的数据库系统这是一种极大的负担。   4、其他   Query Cache因MySql的存储引擎不同而实现略有差异,比如MyISAM,缓存的结果集存储在OS Cache中,而最流行的InnoDB则放在Buffer Pool中。

二、SQL Server的Procedure Cache   SQL Server没有类似MySql的Query Cache机制,但是它有自己的缓存机制。SQL Server不会简单直接地缓存SQL查询结果集,而是缓存它所读取过的查询数据页(数据缓存Data Buffer),同时它还缓存执行计划(过程缓存Procedure Cache),下面就谈谈我们所熟知的过程缓存。

1、SQL执行过程   SQL语句在执行前首先需要被编译,接着需要通过SQL Server查询引擎进行优化,然后得到优化后的执行计划,最后SQL按照执行计划被执行。

2、过程缓存(Procedure Cache)   创建执行计划会占用CPU资源,当执行计划被创建后,SQL Server查询引擎默认会自动缓存执行计划。   对于整体相似,仅仅是参数不同的SQL语句,SQL Server可以重用缓存的执行计划。   但对于不同的SQL语句,SQL Server并不能重复使用以前的执行计划,而需要重新编译出一个新的执行计划,因为SQL Server查询引擎会自动缓存执行计划,每一个新的执行计划都会占用SQL Server的内存。   在SQL Server可用内存足够使用的情况下,查询引擎并不主动清除以前保存的查询计划。所以,某些情况下,一条相似的SQL语句,仅仅因为写法不同,而凭空多出了很多执行计划,对于相似的SQL,这些多余的执行计划白白地占据着内存,大大影响SQL Server中缓存的查询计划数目。   对于上面这种情况,如果限定了SQL Server最大可用内存,它将导致SQL Server可用内存减少,从而在执行查询时尤其是大的数据查询时与磁盘发生更多的内存页交换;如果没有设置最大可用内存,则SQL Server由于缓存了太多执行计划,从而使内存占用过大。

3、如何减少过程缓存 对于减少过程缓存的占用,主要是可以通过使用参数化查询。   参数化查询的关键是查询优化器将创建一个可以重用的缓存计划(SQL Server查询优化器将查询重新编写为一个参数化SQL语句),这个可重用的缓存计划消除了对这些类似SQL语句的每一次执行都创建一个缓存计划的需求。通过创建一个可重用计划,SQL Server就减少了存放类似的执行计划所需的内存使用。   对于开发人员,我们一般可以通过下面两种方式实现参数化查询:

  (1)、使用存储过程执行SQL语句;

  (2)、使用sp_executesql 方式执行SQL语句。   关于使用存储过程执行SQL,再说句题外话:对于存储过程一直以来有颇多争议,比如ORM派认为存储过程是完全面向过程的不易扩展不易维护的等等等等。根据我个人的开发经验,简单的几乎没有逻辑的存储过程我建议多用,但是复杂的存储过程一直以来都是BUG集中营,而且后期维护成本奇高(听我司架构师讲过,某重要业务系统的数据库有个八千多行的存储过程,两百多个变量,没有人敢动),逻辑最好通过应对剧烈变化的业务逻辑层来写。现在我们有了成熟的ORM,还有分层,开发中要绝对避免写过长且逻辑复杂的存储过程,否则面对变化,日积月累再出现几个八千行的存储过程也不是没有可能。

MySql数据库缓存的更多相关文章

  1. 用Redis作Mysql数据库缓存

    使用redis作mysql数据库缓存时,需要考虑两个问题: 1.确定用何种数据结构存储来自Mysql的数据; 2.在确定数据结构之后,用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是按 ...

  2. redis(二)--用Redis作MySQL数据库缓存

    用Redis作MySQL数据库缓存,必须解决2个问题.首先,应该确定用何种数据结构存储来自mysql的数据:在确定数据结构之后,还要考虑用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是 ...

  3. 【数据库】mysql数据库缓存

    配置文件在 /etc/mysql/my.cnf ################### 第一部分:查询数据库缓存相关变量 ################### show variables like ...

  4. mysql 数据库缓存调优之解决The total number of locks exceeds the lock table size错误

    环境: mysql5.6.2  主从同步(备注:需操作主库和从库) 一.InnoDB表执行大批量数据的更新,插入,删除操作时会出现这个问题,需要调整InnoDB全局的innodb_buffer_poo ...

  5. MySQL数据库缓存操作

    安装: 启动的话: -d:以后台的方式进行: -l:选择监听指定的ip服务地址:-m:给他分配多大的内存:-p:端口号默认的端口为11211的服务端口: 另一个: 安装:telnet 这个可以用来测试 ...

  6. 用Redis作为Mysql数据库的缓存【转】

    用Redis作Mysql数据库缓存,必须解决2个问题.首先,应该确定用何种数据结构存储来自Mysql的数据:在确定数据结构之后,还要考虑用什么标识作为该数据结构的键. 直观上看,Mysql中的数据都是 ...

  7. 浅谈MySQL 数据库性能优化

    MySQL数据库是 IO 密集型的程序,和其他数据库一样,主要功能就是数据的持久化以及数据的管理工作.本文侧重通过优化MySQL 数据库缓存参数如查询缓存,表缓存,日志缓存,索引缓存,innodb缓存 ...

  8. 性能测试之Mysql数据库调优

    一.前言 性能调优前提:无监控不调优,对于mysql性能的监控前几天有文章提到过,有兴趣的朋友可以去看一下 二.Mysql性能指标及问题分析和定位 1.我们在监控图表中关注的性能指标大概有这么几个:C ...

  9. 使用Memcache缓存mysql数据库操作的原理和缓存过程浅析

    转载自脚本之家 http://www.jb51.net/article/51831.htm  作者:忙碌的松鼠 对于大型网站如facebook,ebay等网站,如果没有Memcache做为中间缓存层, ...

随机推荐

  1. Swift系列十 - inout的本质

    inout是可以用来在函数内部修改外部属性内存的. 一.inout回顾 示例代码: func test(_ num: inout Int) { num = 20 } var a = 10 test(& ...

  2. window location href is not a function(Day_36)

    报window location href is not a function错误的解决方案: 原因: JS报错是由于写法问题或浏览器不兼容导致的,具体解决方法如下: 原来报错的写法: window. ...

  3. Redis学习笔记七:主从集群

    单机,单节点,单实例的Redis会有什么问题呢? 容易导致单点故障,那么如何解决呢? 可以通过主备方式 同时可以实现读写分离 这里的每个节点是全量的,镜像的. 单节点的容量有限而且单点的压力比较大,如 ...

  4. SystemVerilog MCDF验证结构

    MCDF的设计和验证花费的时间:(工作中假设的时间) design  cycle time  ==10days how about 验证?verify? 模块越往上(大')验证花费的时间越来越大,但是 ...

  5. systemverilog动态数组

  6. 十一、.net core(.NET 6)搭建ElasticSearch(ES)系列之ElasticSearch、head-master、Kibana环境搭建

    搭建ElasticSearch+Kibana环境 前提条件:已经配置好JDK环境以及Nodejs环境.如果还未配置,请查看我的上一篇博客内容,有详细配置教程. 先下载ElasticSearch(以下文 ...

  7. Jmeter- 笔记12 - 性能测试分析 & 性能测试流程

    性能测试分析 场景设计.监视图表: 设计场景:阶梯式.波浪式 监视器: 收集用于性能分析的数据:TPS图表.聚合报告\汇总报告.察看结果树.响应时间.吞吐量 服务器资源监控:cpu.内存.磁盘io 分 ...

  8. maven把依赖打进jar包

    1.把依赖打进sigma-api的jar包 <?xml version="1.0" encoding="UTF-8"?> <project x ...

  9. CVPR2019目标检测论文看点:并域上的广义交

    CVPR2019目标检测论文看点:并域上的广义交 Generalized Intersection over Union Generalized Intersection over Union: A ...

  10. SOLOv 2:实例分割(动态、更快、更强)

    SOLOv 2:实例分割(动态.更快.更强) SOLOv2:  Dynamic, Faster and Stronger 论文链接: https://arxiv.org/pdf/2003.10152. ...