一条SQL语句的奇妙旅程

MySQL的逻辑架构

  1.  链接器:负责用户的身份认证和权限校验。mysql

  2. 查询缓存:这个在8.0之后的版本已经取缔了,可是不影响设计思想的了解,即:当有一个SQL进来的时候,先会去匹配SQL语句,若是本地已经有缓存,即直接读缓存,返回结果。乍一听挺好的功能,为何会被取缔呢?这存在一些设计理念的问题,MySQL追求极高的性能,该功能在实际使用过程当中弊大于利,写缓存/清缓存的过程可能会大幅度影响性能算法

  3. 分析器/解析器:这个模块主要是进行一些语法分析/词法分析,你们可能以为与本身关系不太大,其实咱们初学SQL语句的时候第一个打交道的就是这个模块,好比当你输入错误语句的时候,语法的错误在这层就已经发现了。sql

  4. 预处理器:这个模块会肯定你输入的表和列是否真实存在,字段别名是否有歧义,主要是当你语法没错的时候,肯定是否符合这个场景。数据库

  5. 查询优化器:这能够说是server层最核心也是实战最重要的地方了,首先,咱们每次能够经过explain+sql来查看当前语句的各个属性,这些属性能给咱们调优很好的建议。这点会在下篇文章中细谈,这篇文章整体是为了打通全链路。
    其次,咱们能够根据show warnings来查看查询优化器到底作了哪些优化,从而考虑优化是否得当。缓存

  6. 执行引擎:这块主要是对结果进行过滤和排序,这个模块的命名有些歧义,其实真实的数据检索并不是在这里进行,这层进行的是对检索的结果集进行一次过滤和排序。安全

  7. 存储引擎:这里就是真正的核心了,也就是咱们一直所说的innodb、myisam等存储引擎工做的地方,咱们全部的查询检索任务都是在这里进行的,全部的存储也是在这里进行。这个模块也会在以后的文章中分析。服务器

如今来假设一条SQL来作全套了,那么它会是怎样的一个逻辑呢?

首先咱们客户端与服务器之间会创建一个链接(这里的链接是指那几种进程通讯方式中的一种,大部分状况下说的是TCP/IP进行链接的,过程当中须要咱们mysql -u root -p输入密码,就能够进入mysql。数据结构

此时咱们能够经过SQL语句进行增删改查,当咱们输入一条语句,假若在5.8版本以前,这条语句会进入查询缓存,在这个模块中先对SQL语句进行匹配,假若找到彻底匹配的缓存,则读缓存返回结果,假若没有匹配的,则会进入下一模块。查询到的结果会写进写缓存这也是之因此在5.8之后取缔掉查询缓存的缘由:写缓存对性能是有必定的影响的,事实上这个影响甚至大于其对速度的提高。架构

进入下一模块之后,会对语句进入一些词法分析和语法分析,看看有没有语法上的错误,初学者常常被卡在这个模块,由于语句写的不规范之类的问题。性能

再到后来,这条语句会进入预处理器,也就是看看你虽说的都对,语法都对,可是你搜索的列若是是我根本没有的,那至关于什么都没有,若是一切正常,就再日后走。

此时进入了server层最核心的查询优化器,这里MySQL有本身的想法, 他会对你输入的语句进行一些优化和重排,这里有一个很细节可是很核心的点:任何关联进入查询优化器都会变成嵌套循环关联,也就是说,不少复杂的关联都会变成相似于左链接之类的关联,其缘由也很是简单,正如上述:执行引擎是对结果进行过滤和排序,那么若是咱们能够经过优化语句提早对语句进行过滤,这样就能够大幅度提升性能。当咱们查询Explain+sql语句的时候会出现不少的属性,咱们须要注意的是要避免外部排序的产生,由于这样会产生巨大的性能影响。

查询优化器毕竟不是十全十美的,它的不少优化多是好心没作好事,最典型的就是临时表了,首先临时表这个东西自己是很是好的,它将中间过程的一些结果集存储在内存上,颇有利于查询过程的执行,可是有可能内存不足的状况下,会将数据存储在磁盘上,而磁盘参与读写必定会带来非必要的资源和性能消耗,所以咱们必须结合实际状况考究某些属性的存在是否合理。

查询优化器以后,查询进入了执行引擎,在这里其实并未进行太多的事情,执行引擎主要是调度存储引擎,而后存储引擎在硬盘中去检索,而后拿到结果返回执行引擎,由执行引擎进行结果的过滤和排序,而后返回结果集回到客户端,若是是在5.8之前的话,会放入写缓存。

接下来就是核心的问题了:存储引擎。

咱们经常使用的存储引擎大概是innodb和myisam,这两任默认引擎撑起了MySQL的半边天,如今我会比较粗略的介绍一下两个引擎,详细的文章会在后期输出。

innodb存储引擎与myisam存储引擎

首先咱们先认识所谓存储引擎最重要的两个功能就是存储与查询,那么咱们从存储和查询两个方面来分析一下这两个引擎的特色。

存储方面:
首先当咱们存储数据的时候,由于这两个引擎都是基于磁盘的,innodb是将索引和数据放在一块儿的,这跟其索引结构有关,当进行存储的时候,innodb将全部的数据都存储在一块儿;而myisam则是将索引数据和真实数据分开存储,这样实际上是经过索引进行检索,获得的结果是一个真实数据的指针,而后进入数据文件中进行随机io。这就决定了一点,若是咱们是innodb存储引擎的话,主键尽可能自增,由于若是非自增,会致使不能进行顺序io,性能会有很大的退化。而myisam的数据存储位置不能轻易移动,由于这样会致使索引失效,也会影响性能。

查询方面:
查询就像翻词典同样,索引就像目录和页码,这是很是重要的一部分,不少初学者以为本身很是少用到索引,其实否则,咱们常常用到的主键即是最标准的索引,当你的查询命中索引的时候,即可以进入高速列车,为何呢?由于数据结构,在此强调一下,一直很认同程序=数据结构+算法,数据结构很是重要,若是咱们能命中索引,就能够进入索引的数据结构,此时要么是哈希索引,要么是b+树索引,这两种索引一个的复杂度为O(1),一个是O(log(M)N),其中M为索引关键字,N为总关键字数量,很容易看到,这种速度比全表遍历好了太多了,因此若是命中索引的话,就能够大幅度提升速率。

固然这两点虽然重要,可是都不是两种引擎最大的区别,这两种存储引擎最大的差异在于事务性和锁的粒度上,这也是innodb弯道超车最重要的缘由。

事务性

随着数据库的应用场景愈来愈多,咱们对数据的安全性有了愈来愈多的需求,myisam不支持事务,这致使这种存储引擎很快的落时了。

锁粒度

并非说myisam彻底不考虑数据安全性,只是它的粒度有些太大了,它为了数据的安全直接动用了表级锁,直接致使性能影响太大。

相关文章
相关标签/搜索