开发人员基本都知道,咱们的数据存在数据库中(目前最多的是mysql和oracle,因为做者更擅长mysql,因此这里默认数据库为mysql),服务器经过sql语句将查询数据的请求传入到mysql数据库。数据库拿到sql语句之后。都是进行了哪些操做呢?这里向你们介绍下个人我的的理解,欢迎你们评论区批评指正。mysql
mysql获得sql语句后,大概流程以下:sql
1.sql的解析器:负责解析和转发sql数据库
2.预处理器:对解析后的sql树进行验证缓存
3.查询优化器:获得一个执行计划性能优化
4.查询执行引擎:获得数据结果集服务器
5.将数据放回给调用端。架构
流程图以下所示:并发
首先,若是系统的缓存功能开启着的话,sql语句进入mysql后,sql进行判断,是否为select关键字。若是是,那么先去查询缓存中进行查询,若是在查询缓存中能够命中sql语句,那么直接返回查询缓存中的查询语句对应的value值(在缓存中,把查询语句作一个hash运算,结果做为key值,查询的结果集为value)。oracle
若是命中缓存的话,查询速度是至关快的。可是查询缓存也有它相应的缺点。分布式
首先,开启缓存的话,服务器会消耗大量的内存空间;其次,缓存有的时候并不适用;最后,有的状况下,开启缓存也不会将对应的sql语句写入缓存。
缓存的锁的力度比较大,并且对于动态sql的支持度不够。
缓存在数据进行更新的时候,是进行的表级锁,更新结束后,会把全部与更新内容相关的缓存所有删除。因此,若是表的写入比较多的话,缓存是比较浪费性能的。若是写入特别多,可能缓存反而会致使mysql变慢。
1.查询条件有不肯定数据:如now ,current_time等。
2.缓存对大小写敏感,如select * from test 和SELECT* FROM test 就不会解析为同一条sql
1.开始前须要先检查缓存是否命中。
2.结果输出的时候,须要额外进行数据的缓存操做。
3.写入数据时,mysql会将对应表的全部缓存都设置为失效。当缓存内存较大的时候,会致使系统消耗较大。
sql解析器是在命令分发以后,将对应的sql语句,解析为sql解析树。sql解析树是Mysql自己内部的语法规则和解析查询。验证是否使用错误的关键字,sql语法顺序是否正确等。(语法层面的错误)
解析完成后,进行查询语句预处理器,根据mysql的规则,检查解析树是否合法。(表格是否存在,别名是否有歧义等)
查询优化器获取到执行计划而后由查询执行引擎执行相应的操做。查询优化器,是数据库l的一个核心模块,分为cbo和rbo两种。
其中,rbo是基于规则的优化器。(rbo在oracle早期版本中使用,如今也保留,不过默认为cbo。mysql没有rbo优化器)
这些规则是硬编码在数据库的代码中的。rbo会根据输入的sql语句能够匹配到的优先级最高的规则去做为执行计划。例如:在rbo中有这么一条规则:有索引的状况下,使用索引。那么全部的带有索引的表在执行的时候,都会走索引。rbo最大的问题在于,经过固定规则来决定执行计划。并不会考虑sql中涉及的对象的数量和分布。有可能选出来的规则不是最优的执行计划。
cbo 是基于成本的优化器(基于统计信息),从目标诸多的执行路径中选择一个成本最小的执行路径来做为执行计划。成本指的是mysql根据相关的统计信息,算出来sql语句对应的io,cpu等的消耗的一个估计值。计算过程涉及到索引、表、行等数据,过程比较复杂。
1.查询优化器使用统计信息为sql选择执行计划。
2.mysql没有数据直方图,也没法手工删除统计信息。(oracle有)
3.在服务器曾有查询优化器,却没有保存数据和索引统计信息。统计信息由存储引擎实现,不一样的存储引擎会存储不一样的统计信息。
4.统计信息分为索引的统计信息和表的统计信息。
索引统计信息
show index from table 或information_schema.statistics表
表统计信息
show table status like 或 information_schema.tables表
获得执行计划后,根据已有的执行计划,查询执行引擎,mysql的SQL Layer层,调用Storage Engine Layer层的接口,从mysql的存储引擎中获取到相对应的结果集,而后返回给用户。
执行完成后,将结果返回给客户端,若是是查询语句,而且开启了缓存,那么,mysql会同时将结果集放到查询缓存中。而后将查到的结果集返回。若是是增删改操做,那么返回执行语句后受影响的行数。
顺便给你们推荐一个Java架构方面的交流学习群:698581634,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系,主要针对Java开发人员提高本身,突破瓶颈,相信你来学习,会有提高和收获。在这个群里会有你须要的内容 朋友们请抓紧时间加入进来吧。