数据库

MySQL的逻辑架构

2019-02-17  本文已影响97人  芒果菠萝蛋炒饭

MySQL的逻辑架构

MySQL的架构分为三层:

MySQL的查询过程

1. 客户端/服务器通信协议:  
在任一时刻, 要么是服务器向客户端发送数据,要么是客户端向服务器发送数据,这两个动作不能同时发生。  
一旦一端开始发送消息,另一端要接收完整个消息才能响应它。  
服务端响应客户端请求时,客户端必须接收整个返回结果。因此在实际开发中,应该尽量保持查询简单且只返回必须的数据,这也是查询中尽量避免使用 `SELECT *` 和 `LIMIT` 的原因之一。

2. 查询缓存  
- 在查询缓存打开的情况下,解析一个查询语句的时候,MySQL会先检查这个查询缓存是否命中查询缓存中的数据。如果当前查询恰好命中查询缓存,在检查用户权限之后,会直接返回缓存中的结果,这种情况下查询不会被解析,不会生成执行计划,更不会执行。  
- MySQL将缓存存放在一个引用表(类似于HashMap的数据结构),通过一个哈希值索引,这个哈希值通过查询本身、当前要查询的数据库、客户端协议版本号等一些可能影响结果的信息计算得来。所以两个查询在任何字符上的不同(例如:空格、注释),都会导致缓存不会命中。  
- 如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、mysql库中的系统表,其查询结果都不会被缓存。因为同一个函数调用返回的结果可能不同(如 `NOW()` `CURRENT_USER`等),这样的查询结果缓存起来没有意义。
- 是缓存,就会失效,那查询缓存何时失效呢?  
MySQL的查询缓存系统会跟踪查询中涉及的每个表,如果这些表(数据或结构)发生变化,那么和这张表相关的所有缓存数据都将失效。正因为如此,在任何的写操作时,MySQL必须将对应表的所有缓存都设置为失效。如果查询缓存非常大或者碎片很多,这个操作就可能带来很大的系统消耗。除了写操作,读操作也会造成系统消耗:  
    1. 任何的查询语句在开始之前都必须经过检查,即使这条SQL语句永远不会命中缓存
    2. 如果查询结果可以被缓存,那么执行完成后,会将结果存入缓存,也会带来额外的系统消耗  

    基于此,我们要知道并不是什么情况下查询缓存都会提高系统性能,缓存和失效都会带来额外消耗,只有当缓存带来的资源节约大于其本身消耗的资源时,才会给系统带来性能提升。

- 如果系统确实存在一些性能问题,可以尝试打开查询缓存,并在数据库设计上做一些优化,比如:

    - 用多个小表代替一个大表,注意不要过度设计
    - 批量插入代替循环单条插入
    - 合理控制缓存空间大小,一般来说其大小设置为几十兆比较合适
    - 可以通过SQL_CACHE和SQL_NO_CACHE来控制某个查询语句是否需要进行缓存

语法解析和预处理

性能优化建议

上一篇 下一篇

猜你喜欢

热点阅读