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]>