逻辑架构mysql
MySQL逻辑架构总体分为三层:sql
存储引擎数据库
主要介绍InnoDB引擎和MyISAM引擎缓存
InnoDB引擎:安全
MyISAM引擎:服务器
查询过程数据结构
咱们但愿经过MySQL能够得到更好的查询性能,最好的方式就是弄清楚MySQL是如何执行查询的,理解了这一点,咱们能够依据它的规则去优化SQL语句。架构
当向MySQL发送一个SQL请求的时候,究竟发生了什么呢,以下:并发
客户端/服务端通讯协议数据库设计
一、MySQL客户端/服务端通讯协议是半双工的:在任一时刻,要么是服务器向客户端发送数据,要么是客户端向服务器发送数据,这两个动做不能同时发生。一旦一端开始发送消息,另外一端要接收完整个消息才能响应它,因此咱们没法将一个消息切成小块独立发送,也没有办法进行流量控制。
二、客户端用一个单独的数据包将查询请求发送给服务器,因此当查询语句很长的时候,须要设置max_allowed_packet参数。可是须要注意的是,若是查询实在是太大,服务端会拒绝接收更多数据并抛出异常。
三、服务器响应给用户的数据一般会不少,由多个数据包组成。可是当服务器响应客户端请求时,客户端必须完整的接收整个返回结果,而不能只取部分结果,而后让服务器中止发送。于是在实际开发中,尽可能保持查询简单且只返回必需的数据,减少通讯间数据包的大小和数量是一个很是好的习惯,这也是查询中尽可能避免使用SELECT *以及加上LIMIT限制的缘由之一。
小结:请求语句有大小限制,不该过长;减少通讯间数据包大小及通讯数量
查询缓存
在解析一个查询语句前,若是查询缓存是打开的,那么MySQL会检查这个查询语句是否命中查询缓存中的数据。若是当前查询刚好命中查询缓存,在检查一次用户权限后直接返回缓存中的结果。这种状况下,查询不会被解析,也不会生成执行计划,更不会执行。
MySQL将缓存存放在一个引用表(相似于HashMap的数据结构),经过一个哈希值索引,这个哈希值经过查询语句、查询的数据库、客户端协议版本号等一些可能影响结果的信息计算得来。因此两个查询在任何字符上的不一样(例如:空格、注释),都会致使缓存不会命中。
若是查询中包含任何用户自定义函数、存储函数、用户变量、临时表、mysql库中的系统表,其查询结果都不会被缓存。好比函数NOW()或者CURRENT_DATE()会由于不一样的查询时间,返回不一样的查询结果,再好比包含CURRENT_USER或者CONNECION_ID()的查询语句会由于不一样的用户而返回不一样的结果,将这样的查询结果缓存起来没有任何的意义。
MySQL的查询缓存系统会跟踪查询中涉及的每一个表,若是这些表(数据或结构)发生变化,那么和这张表相关的全部缓存数据都将失效。正由于如此,在任何的写操做时,MySQL必须将对应表的全部缓存都设置为失效。若是查询缓存很是大或者碎片不少,这个操做就可能带来很大的系统消耗,甚至致使系统僵死一下子。
查询缓存对系统的额外消耗不只仅在写操做,读操做也不例外:
不要轻易打开查询缓存,特别是写密集型应用。若是必定要开启查询缓存,能够将query_cache_type设置为DEMAND,只有查询语句加入SQL_CACHE的查询才会走缓存,其余查询则不会,这样能够很是自由地控制哪些查询须要被缓存。
语法解析和预处理
MySQL经过关键字将SQL语句进行解析,而且建立内部数据结构解析树,这个过程解析器主要经过语法规则来验证和解析,好比是否使用了错误的关键字,查询的数据表和列是否存在等,而后对其进行各类优化,包括重写查询,决定表的读写顺序,以及选择合适的索引等。用户能够经过特殊的关键字提示(hint)优化器,影响它的决策过程。也能够请求优化器解释(explain)优化过程的各个因素,使用户知道服务器如何进行优化决策的,这个比较实用,尤为是优化某个查询语句时。