vlambda博客
学习文章列表

聊聊mysql执行过程



在项目开发当中 ,很多时候,我们的数据库应用优化都是从表层到里层的一个过程。比如一个查询写下来 ,我们的优化方向大多时候都是先看方法执行的时间长短,然后再决定是否去优化它,下意识的第一步操作都是看是否命中索引,接下去再看数据量、设计是否合理。。。等等。



那么其实在我们一开始的时候,如果我们事先知道数据库的一个执行流程,我们就可以按照他的规则去写sql,进而提高性能和开发效率。



这点有点像前些年 我们国家做出口的时候  开始的时候没有吃透人家的一些法律规则 导致出现违规不合格的情况  进而被退货造成损失。所以熟悉游戏规则很重要。


很多的查询优化工作实际上就是遵循一些原则让MySQL的优化器能够按照预想的合理方式运行而已。比如索引。



下面看下一条sql 的执行过程。分为5个步骤。

图片来源网络




1、连接器


负责与客户端的通信,是半双工模式,这就意味着某一固定时刻只能由客户端向服务器请求或者服务器向客户端发送数据,而不能同时进行,其中mysql在与客户端连接TC/IP的;


验证请求用户的账户和密码是否正确;


如果用户的账户和密码验证通过,会在mysql自带的权限表中查询当前用户的权限:


说白了,就是我们的数据库连接串连接到数据库的过程。




2、缓存


    mysql的缓存主要的作用是为了提升查询的效率,缓存以key和value的哈希表形式存储,key是具体的sql语句,value是结果的集合。如果无法命中缓存,就继续走到分析器的的一步,如果命中缓存就直接返回给客户端 。,目前在5.6的版本中已经默认关闭了。如果读写很频繁的话,依赖命中率低,二来频繁的缓存操作反而性能更低。


3、分析器



   分析器的主要作用是将客户端发过来的sql语句进行分析,这将包括预处理与解析过程,在这个阶段会解析sql语句的语义,并进行关键词和非关键词进行提取、解析,并组成一个解析树。如果分析到语法错误,会直接给客户端抛出异常。就是一个sql格式化的过程。


4、优化器


这部主要是进行sql语句的优化,会根据执行计划进行最优的选择,匹配合适的索引,选择最佳的执行方案。


比如一个典型的例子是这样的:


表T,对A、B、C列建立联合索引,在进行查询的时候,当sql查询到的结果是:select xx where  B=x and A=x and C=x.很多人会以为是用不到索引的,但其实会用到,虽然索引必须符合最左原则才能使用,但是本质上,优化器会自动将这条sql优化为:where A=x and B=x and C=X,这种优化会为了底层能够匹配到索引,同时在这个阶段是自动按照执行计划进行预处理,mysql会计算各个执行方法的最佳时间,最终确定一条执行的sql交给最后的执行器。


所以我们在写sql的时候,最好是按照建立好的索引顺序来添加查询条件,等于就省去了优化的时候,进而提高效能。




5、执行器


 在执行器的阶段,此时会调用存储引擎的API,API会调用存储引擎,常用的是myisam和innodb:


myisam 不支持事务 ,不支持行锁,支持表锁,适合读多写少。


innodb  支持行锁 表锁,支持事务。应该是用的最多的存储引擎,也是mysql默认的存储引擎。



终上所述


客户端 ----> 连接器 ----> 缓存 ----> 分析器 ----> 优化器 ----> 执行器 ----> 存储引擎 ----> 客户端