没有合适的资源?快使用搜索试试~ 我知道了~
资源详情
资源评论
资源推荐
说起 MySQL 的查询优化,相信大家收藏了一堆奇技淫巧:不能使用
SELECT *、不使用 NULL 字段、合理创建索引、为字段选择合适的数
据类型..... 你是否真的理解这些优化技巧?是否理解其背后的工作原
理?在实际场景下性能真有提升吗?我想未必。因而理解这些优化建
议背后的原理就尤为重要,希望本文能让你重新审视这些优化建议,
并在实际业务场景下合理的运用。
MySQL 逻辑架构
如果能在头脑中构建一幅 MySQL 各组件之间如何协同工作的架构图,
有助于深入理解 MySQL 服务器。下图展示了 MySQL 的逻辑架构图。
MySQL 逻辑架构,来自:高性能 MySQL
MySQL 逻辑架构整体分为三层,最上层为客户端层,并非 MySQL 所
独有,诸如:连接处理、授权认证、安全等功能均在这一层处理。
MySQL 大多数核心服务均在中间这一层,包括查询解析、分析、优化、
缓存、内置函数(比如:时间、数学、加密等函数)。所有的跨存储引
擎的功能也在这一层实现:存储过程、触发器、视图等。
最下层为存储引擎,其负责 MySQL 中的数据存储和提取。和 Linux
下的文件系统类似,每种存储引擎都有其优势和劣势。中间的服务层
通过 API 与存储引擎通信,这些 API 接口屏蔽了不同存储引擎间的差
异。
MySQL 查询过程
我们总是希望 MySQL 能够获得更高的查询性能,最好的办法是弄清
楚 MySQL 是如何优化和执行查询的。一旦理解了这一点,就会发现:
很多的查询优化工作实际上就是遵循一些原则让 MySQL 的优化器能
够按照预想的合理方式运行而已。
当向 MySQL 发送一个请求的时候,MySQL 到底做了些什么呢?
MySQL 查询过程
客户端/服务端通信协议
MySQL 客户端/服务端通信协议是“半双工”的:在任一时刻,要么是服
务器向客户端发送数据,要么是客户端向服务器发送数据,这两个动
作不能同时发生。一旦一端开始发送消息,另一端要接收完整个消息
才能响应它,所以我们无法也无须将一个消息切成小块独立发送,也
没有办法进行流量控制。
客户端用一个单独的数据包将查询请求发送给服务器,所以当查询语
句很长的时候,需要设置 max_allowed_packet 参数。但是需要注
意的是,如果查询实在是太大,服务端会拒绝接收更多数据并抛出异
常。
与之相反的是,服务器响应给用户的数据通常会很多,由多个数据包
组成。但是当服务器响应客户端请求时,客户端必须完整的接收整个
返回结果,而不能简单的只取前面几条结果,然后让服务器停止发送。
因而在实际开发中,尽量保持查询简单且只返回必需的数据,减小通
信间数据包的大小和数量是一个非常好的习惯,这也是查询中尽量避
免使用 SELECT *以及加上 LIMIT 限制的原因之一。
查询缓存
在解析一个查询语句前,如果查询缓存是打开的,那么 MySQL 会检
查这个查询语句是否命中查询缓存中的数据。如果当前查询恰好命中
查询缓存,在检查一次用户权限后直接返回缓存中的结果。这种情况
下,查询不会被解析,也不会生成执行计划,更不会执行。
MySQL 将缓存存放在一个引用表(不要理解成 table,可以认为是类
似于 HashMap 的数据结构),通过一个哈希值索引,这个哈希值通
过查询本身、当前要查询的数据库、客户端协议版本号等一些可能影
响结果的信息计算得来。所以两个查询在任何字符上的不同(例如:
空格、注释),都会导致缓存不会命中。
如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、
mysql 库中的系统表,其查询结果
都不会被缓存。比如函数 NOW()或者 CURRENT_DATE()会因为不同
的查询时间,返回不同的查询结果,再比如包含 CURRENT_USER 或
者 CONNECION_ID()的查询语句会因为不同的用户而返回不同的结果,
将这样的查询结果缓存起来没有任何的意义。
既然是缓存,就会失效,那查询缓存何时失效呢?MySQL 的查询缓存
系统会跟踪查询中涉及的每个表,如果这些表(数据或结构)发生变
化,那么和这张表相关的所有缓存数据都将失效。正因为如此,在任
何的写操作时,MySQL 必须将对应表的所有缓存都设置为失效。如果
查询缓存非常大或者碎片很多,这个操作就可能带来很大的系统消耗,
甚至导致系统僵死一会儿。而且查询缓存对系统的额外消耗也不仅仅
在写操作,读操作也不例外:
. 任何的查询语句在开始之前都必须经过检查,即使这条 SQL 语句永远
不会命中缓存
. 如果查询结果可以被缓存,那么执行完成后,会将结果存入缓存,也
会带来额外的系统消耗
基于此,我们要知道并不是什么情况下查询缓存都会提高系统性能,
缓存和失效都会带来额外消耗,只有当缓存带来的资源节约大于其本
身消耗的资源时,才会给系统带来性能提升。但要如何评估打开缓存
是否能够带来性能提升是一件非常困难的事情,也不在本文讨论的范
畴内。如果系统确实存在一些性能问题,可以尝试打开查询缓存,并
在数据库设计上做一些优化,比如:
剩余33页未读,继续阅读
sbps120
- 粉丝: 0
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 2%EF%BC%9A%E9%99%95%E8%A5%BF%E
- yyspdz62_944.apk
- SAP公司间采购EDI配置-如何触发自动MIRO.docx
- python197基于图像识别的仪表实时监控系统.rar
- I2C驱动SHT30温湿度传感器和LCD12864使用例程(RSCG12864B)
- python193中学地理-中国的江河湖泊教学网(django).rar
- python191基于时间序列分析的大气污染预测软件(django).rar
- python190基于人脸识别智能化小区门禁管理系统.rar
- python189某医院体检挂号系统.rar
- python179的企业物流管理系统(django).rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0