MySQL/MariaDB数据库的查询缓存优化

                            作者:尹正杰 

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.MySQL架构

Connectors(MySQL对外提供的交互接口,API):
  Connectors组件,是MySQL向外提供的交互组件,如Python,Golang,Java,C++,Php等语言可以通过该组件来操作SQL语句,实现与SQL的交互。 Connection Pool(连接池组件):
  负责监听对客户端向MySQL Server端的各种请求,接收请求,转发请求到目标模块。每个成功连接MySQL Server的客户请求都会被创建或分配一个线程,该线程负责客户端与MySQL Server端的通信,接收客户端发送的命令,传递服务端的结果信息等。 SQL Interface(SQL接口组件):
   接收用户SQL命令,检查SQL语法是否正确,如DML,DDL和存储过程等,并将最终结果返回给用户。 Parser(查询分析器组件):
  首先分析SQL命令语法的合法性,并尝试将SQL命令分解成数据结构(将SQL指令转换成二进制格式来执行),若分解失败,则提示SQL语句不合理。 Optimlzer(优化器组件):
  对SQL命令按照标准流程进行优化分析,选择最佳的查询路径。 Caches & Buffers(缓存主件):
  缓存和缓冲组件 Pluggable Storage Engines(插件式存储引擎):
  通过插件式存储引擎访问真正存储数据,常见的存储引擎有MyISAM,InnoDB等。 File system(文件系统):
  存储引擎会帮我们和操作系统打交道,大家都直到数据持久化存储的依旧式在本地磁盘上。支持不同的文件系统,包括NTFS,EXT2/3/4,NFS,XFS等。 FIle & Logs:
  各种各样的数据库相关文件,如数据文件,日志文件等,如Redo(重做),Undo(撤销)等。 Management Service & Utilities(管理服务组件和工具组件):
  提供对MySQL的集成管理,如备份(Backup),恢复(Recovery),安全管理(Security)等

二.查询的执行路径

MySQL 整个查询执行过程,总的来说分为 5 个步骤 :
  1.客户端向 MySQL 服务器发送一条查询请求
  2.服务器首先检查查询缓存,如果命中缓存,则立刻返回存储在缓存中的结果,否则进入下一阶段
  3.服务器进行 SQL解析、预处理、再由优化器生成对应的执行计划
  4.MySQL 根据执行计划,调用存储引擎的 API来执行查询
  5.将结果返回给客户端,同时缓存查询结果

三.查询缓存 

1>.查询缓存( Query Cache )原理

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

2>.查询缓存( Query Cache )优缺点

  不需要对SQL语句做任何解析和执行,当然语法解析必须通过在先,直接从Query Cache中获得查询结果,提高查询性能

  查询缓存的判断规则,不够智能,也即提高了查询缓存的使用门槛,降低其效率;

  查询缓存的使用,会增加检查和清理Query Cache中记录集的开销

3>.哪些查询可能不会被缓存

  查询语句中加了SQL_NO_CACHE参数;

  查询语句中含有获得值的函数,包含自定义函数,如:NOW(),CURDATE(),GET_LOCK(),RAND(),CONVERT_TZ()等;

  对系统数据库的查询:mysql、information_schema 查询语句中使用SESSION级别变量或存储过程中的局部变量;

  查询语句中使用了LOCK IN SHARE MODE、FOR UPDATE的语句,查询语句中类似SELECT …INTO 导出数据的语句;

  对临时表的查询操作;存在警告信息的查询语句;不涉及任何表或视图的查询语句;某用户只有列级别权限的查询语句;

  事务隔离级别为Serializable时,所有查询语句都不能缓存。

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

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

  query_cache_limit:
    单个查询结果能缓存的最大值,在MariaDB 10.2.x版本中默认为10M,对于查询结果过大而无法缓存的语句,建议使用SQL_NO_CACHE
  
  query_cache_size:
    查询缓存总共可用的内存空间;单位字节,必须是1024的整数倍,最小值40KB,低于此值有警报
  
  query_cache_wlock_invalidate:
    如果某表被其它的会话锁定,是否仍然可以从查询缓存中返回结果,默认值为OFF,表示可以在表被其它会话锁定的场景中继续从缓存返回数据;ON则表示不允许
  
  query_cache_type:
    是否开启缓存功能,取值为ON, OFF, DEMAND
MariaDB [yinzhengjie]> SHOW VARIABLES LIKE 'query_cache%';        #查看Mariadb 10.2.x默认的缓存相关服务器变量。
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| query_cache_limit | 1048576 | #默认是10M
| query_cache_min_res_unit | 4096 | #默认是4K
| query_cache_size | 1048576 | #默认是10M
| query_cache_strip_comments | OFF |
| query_cache_type | OFF | #很显然,默认是没有开启缓存的
| query_cache_wlock_invalidate | OFF | #默认是关闭的
+------------------------------+---------+
rows in set (0.00 sec) MariaDB [yinzhengjie]>
MariaDB [yinzhengjie]>

MariaDB [yinzhengjie]> SHOW VARIABLES LIKE 'query_cache%';    #查看默认的缓存相关服务器变量(优化查询缓存流程图如下)

5>.SELECT语句的缓存控制

  SQL_CACHE:
    显式指定存储查询结果于缓存之中
  
  SQL_NO_CACHE:
    显式查询结果不予缓存

6>.query_cache_type参数变量

  query_cache_type的值为OFF或0时,查询缓存功能关闭

  query_cache_type的值为ON或1时,查询缓存功能打开,SELECT的结果符合缓存条件即会缓存,否则,不予缓存,显式指定SQL_NO_CACHE,不予缓存,此为默

  query_cache_type的值为DEMAND或2时,查询缓存功能按需进行,显式指定SQL_CACHE的SELECT语句才会缓存;其它均不予缓存

  博主推荐阅读:
    https://mariadb.com/kb/en/library/server-system-variables/#query_cache_type
    https://dev.mysql.com/doc/refman/5.7/en/query-cache-configuration.html

7>.查询缓存相关的状态变量

  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 数量
MariaDB [yinzhengjie]> SHOW GLOBAL STATUS LIKE 'Qcache%';         #查询MariaDB 10.2.x 缓存相关的状态变量
+-------------------------+---------+
| Variable_name | Value |
+-------------------------+---------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 1031336 |
| Qcache_hits | 0 |
| Qcache_inserts | 0 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 0 |
| Qcache_queries_in_cache | 0 |
| Qcache_total_blocks | 1 |
+-------------------------+---------+
8 rows in set (0.00 sec) MariaDB [yinzhengjie]>

MariaDB [yinzhengjie]> SHOW GLOBAL STATUS LIKE 'Qcache%';       #查询MariaDB 10.2.x 缓存相关的状态变量

8>.查询缓存中内存块的最小分配单位query_cache_min_res_unit计算公式

  (query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache

9>.查询缓存命中率计算公式

  Qcache_hits / ( Qcache_hits + Qcache_inserts ) * 100%

10>.查询缓存内存使用率计算公式

  (query_cache_size – qcache_free_memory) / query_cache_size * 100%

四.InnoDB存储引擎缓存

1>.InnoDB存储引擎的缓冲池

  通常InnoDB存储引擎缓冲池的命中不应该小于99%.

2>.查看相关状态变量

  Innodb_buffer_pool_reads: 
    表示从物理磁盘读取页的次数

  Innodb_buffer_pool_read_ahead:
    预读的次数

  Innodb_buffer_pool_read_ahead_evicted:
    预读页,但是没有读取就从缓冲池中被替换的页数量,一般用来判断预读的效率

  Innodb_buffer_pool_read_requests:
    从缓冲池中读取页次数

  Innodb_data_read:
    总共读入的字节数

  Innodb_data_reads:
    发起读取请求的次数,每次读取可能需要读取多个页
MariaDB [yinzhengjie]> SHOW GLOBAL STATUS LIKE 'innodb%read%';           #查看MariaDB 10.2.x默认相关状态变量
+--------------------------------------------------------+---------+
| Variable_name | Value |
+--------------------------------------------------------+---------+
| Innodb_buffer_pool_read_ahead_rnd | 0 |
| Innodb_buffer_pool_read_ahead | 0 |
| Innodb_buffer_pool_read_ahead_evicted | 0 |
| Innodb_buffer_pool_read_requests | 2951 |
| Innodb_buffer_pool_reads | 369 |
| Innodb_data_pending_reads | 0 |
| Innodb_data_read | 6113792 |
| Innodb_data_reads | 390 |
| Innodb_pages_read | 368 |
| Innodb_pages0_read | 11 |
| Innodb_rows_read | 179 |
| Innodb_system_rows_read | 0 |
| Innodb_secondary_index_triggered_cluster_reads | 0 |
| Innodb_secondary_index_triggered_cluster_reads_avoided | 0 |
| Innodb_encryption_rotation_pages_read_from_cache | 0 |
| Innodb_encryption_rotation_pages_read_from_disk | 0 |
+--------------------------------------------------------+---------+
16 rows in set (0.00 sec) MariaDB [yinzhengjie]>

MariaDB [yinzhengjie]> SHOW GLOBAL STATUS LIKE 'innodb%read%';     #查看MariaDB 10.2.x默认相关状态变量

3>.Innodb缓冲池命中率计算公式

  (Innodb_buffer_pool_read_requests)/(Innodb_buffer_pool_read_requests + Innodb_buffer_pool_read_ahead + Innodb_buffer_pool_reads)

4>.平均每次读取的字节数计算公式

  Innodb_data_read/Innodb_data_reads

MySQL/MariaDB数据库的查询缓存优化的更多相关文章

  1. MySQL/MariaDB数据库的索引工作原理和优化

    MySQL/MariaDB数据库的索引工作原理和优化 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 实际工作中索引这个技术是影响服务器性能一个非常重要的指标,因此我们得花时间去了 ...

  2. MySQL/MariaDB数据库的多表查询操作

    MySQL/MariaDB数据库的多表查询操作 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.单表查询小试牛刀 [root@node105.yinzhengjie.org.cn ...

  3. MySQL/MariaDB数据库的PROXY实现读写分离

    MySQL/MariaDB数据库的PROXY实现读写分离 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.ProxySQL概述 1>.各家互联网公司读写分离的解决方案 m ...

  4. MySQL/MariaDB数据库的mysqldump工具备份还原实战

    MySQL/MariaDB数据库的mysqldump工具备份还原实战 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.mysqldump概述 1>.逻辑备份工具 mysq ...

  5. MySQL/MariaDB数据库的各种日志管理

    MySQL/MariaDB数据库的各种日志管理 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.事务日志 (transaction log) 1>.Innodb事务日志相 ...

  6. MySQL/MariaDB数据库的并发控制

    MySQL/MariaDB数据库的并发控制 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.并发控制概述 1>.什么是并发控制 MySQL是一个服务器级别的数据库,它通常 ...

  7. MySQL/MariaDB数据库的存储引擎

    MySQL/MariaDB数据库的存储引擎 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一.MySQL体系结构 连接管理模块: 负责接收远程用户的连接. 线程管理模块: 维护 ...

  8. mysql如何执行关联查询与优化

    mysql如何执行关联查询与优化 一.前言 在数据库中执行查询(select)在我们工作中是非常常见的,工作中离不开CRUD,在执行查询(select)时,多表关联也非常常见,我们用的也比较多,那么m ...

  9. MySQL/MariaDB数据库的性能测试

      MySQL/MariaDB数据库的性能测试 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数据库服务衡量指标 qps: query per second(每秒支持多少查询 ...

随机推荐

  1. IDEA中Lombok插件的安装及使用

    这个插件的好处在于可以让我们的代码更简洁,减少一些重复的工作,最常用的就是@Data注解,比如在实体类上使用@Data注解,实体类的各个属性就不需要书写get和set方法. 安装方法: 1.File→ ...

  2. Kubernetes 原理架构介绍(一)

    目录 一.Kubernetes 是什么 二.Kubernetes 设计架构 三.Kubernetes的核心技术概念和API对象 Cluster Master Node Pod Controller D ...

  3. dockerfile使用

    一.构筑镜像命令 docker build -t test/nginx:v1.0 - prese/nginx:v1.0 -f /git/dockerfile . -t:指定存储库:镜像名和标签保存新镜 ...

  4. WIFI-Direct(Wifi直连)、AirPlay、DLAN、Miracast功能介绍

    不知道大家对无线同屏技术有多少了解,当这种技术普及的时候,我想我们的工作与生活又会方便很多吧!下面是目前三种主流同屏技术的介绍: 目前这种将终端信号经由WiFi传输到电视.电视盒的技术有三种:DLNA ...

  5. Delphi编码与签名【URL编码与解码,Base64编码与解码,MD5加密,HMAC-SHA1、HMAC-SHA224、HMAC-SHA256、HMAC-SHA384和HMAC-SHA512签名】

    作者QQ:(648437169) 点击下载➨delphi编码与签名 [Delphi编码与签名]URL编码与解码,Base64编码与解码,MD5加密,HMAC-SHA1.HMAC-SHA224.HMAC ...

  6. DS DI ES SI等等

    DS is called data segment register. It points to the segment of the data used by the running program ...

  7. GreenPlum 最佳实践

    数据模型 Greenplum数据库是一种shared nothing的分析型MPP数据库.这种模型与高度规范化的/事务型的SMP数据库有显著区别.Greenplum数据库使用非规范化的模式设计会工作得 ...

  8. .NET Core随笔把数据库数据查出来转JSON并输出

    直接创建WEB项目即可: public class Startup { //startup.cs是站点启动时具体做了哪些事情,主要是开启了一个mvc服务. public Startup(IConfig ...

  9. golang中生成读取二维码(skip2/go-qrcode和boombuler/barcode,tuotoo/qrcode)

     1 引言 在github上有好用golan二维码生成和读取库,两个生成二维码的qrcode库和一个读取qrcode库. skip2/go-qrcode生成二维码,github地址:https://g ...

  10. centos7#yum install ffmpeg

    yum install ffmpeg rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro rpm -Uvh http://li. ...