select*fromXXXwhereid=1;这应该是n年前入门mysql必用的查询语句。学习如逆水行舟。不进则退。Mysql内部这条语句的执行过程你知道吗?下面我们来看一下常见的Mysql基本架构图。可以看到Mysql可以分为Server层,包括connector、querycache、analyzer、optimizer、executor等,除了直接登陆磁盘,从磁盘提取数据之外的所有能力。存储引擎层负责数据的读取和存储,支持InnoDB、MyISAM、Memory等多种存储引擎。默认是InnoBD。结构大致完成。是不是感觉Mysql就像一个大型的加工厂。你把原材料,也就是sql语句,然后Mysql会反过来给你从头到尾处理,最后做出一个产品。是执行结果。嗯,这个比喻好,真他妈的像,那么这个加工厂到底是做什么的呢?连接器小姐姐首先,我们会使用连接命令连接mysqlmysql-hip-pport-u$user-p这时候出来接待我们的是连接器小姐姐。connector小姐姐负责和我们进行一次典型的TPC握手,然后开始询问我们的身份,需要我们使用芝麻开门的密码来验证是否有权限。如果账号或密码错误,会直接告诉我们“Accessdeniedforuser”已经通过验证,我们和connector的连接已经成功恢复。您可以使用showprocesslist查看连接状态。睡眠状态表明它是一个空闲连接。建立连接后,connector小姐姐还会告诉我们一些规则,比如如果长时间没有动静,连接会自动断开。默认值为8小时。如果连接断开了,当我再次发送请求时,connector会变小妹子会告诉我们LostconnectiontoMySQLserverduringquery,那能改吗?可以,我们只需要告诉connector小姐姐修改wait_timeout的参数即可。听起来像是长连接,所以你可以做一个短连接是吗?是的,connector小姐姐说:如果你和我建立长连接,连接成功后,你以后的请求总是使用同一个连接。但是如果是短连接,我每次操作几下就断开了。下次,您可以再次建立连接。我们也可以看到,其实是和connector的小姐姐建立了连接。过程很麻烦,所以我们平时尽量减少这种行为,一般都是使用长连接。但是啊,有时候我用,mysql的内存增长的很快。为什么是这样?我特意问了connector小姐姐,她告诉我mysql在执行过程中临时使用的内存是在connection对象中管理的。是的,而且这些对象只有在连接断开的时候才会被释放,所以内存占用越来越大,最后可能会被系统强行杀掉,也就是OOM损失。如果这么严重,那我应该用长连接还是短连接呢??一定是长连接。别着急,还是有解决办法的。我们给出了两种解决方案,定期断开长连接,使用一段时间,或者程序判断执行完占用内存的大查询后断开。连接,然后检查并重新连接。如果您使用的是MySQL5.7或更新版本,则可以在每次大型操作后执行mysql_reset_connection来重新初始化连接资源。这个过程不需要重新连接和重新认证,但会将连接恢复到刚刚创建的状态。到了这里连接器小姐姐的工作就结束了,后面出来接待我们的小哥哥就是缓存查询的小哥哥了。缓存查询小哥缓存查询小哥也比较简单,我们一开始对比我们的sql语句,他那边有一个字典,以key-value格式记录查询的key和结果,他的方法也极其简单。只要找到相同的,结果就会返回给我们。只有找不到记录的时候,才会继续按照流程继续往字典里记录。这时,我很困惑。如果数据实际上已更新,但您的字典仍然很旧怎么办?缓存查询小哥说,这个不用管,字典会记录查询记录对应的表,如果对应的表已经更新过,我会清空这里的所有记录。哦,像这样,如果更新比较频繁,你可能用处不大哈哈哈可以的,你可以通过query_cache_type=DEMAND关掉,从8.0开始,我去掉了。说完缓存查询,小哥流下了悲伤的泪水,是的,毕竟技术跟不上时代,被淘汰在所难免。缓存查询师兄说完,又叫出了另一个师兄。这位小弟叫做分析器。分析器小哥拿到sql语句后,分析器小哥就开始自己动手捣鼓了,那到底是干什么的呢?我们看了半天,其实他做了两步,第一步,词法分析,就是从SQL语句中提取关键字,比如:查询表,字段名,查询条件等等。第二步,语法规则,判断SQL语句是否符合MySQL的语法。分析器小哥的所作所为我也明白了。词法分析其实就是将整条SQL语句拆分成词,语法规则根据MySQL定义的语法规则生成相应的数据结构,存储在对象结构中。之中。例如,假设有这样一条SQL语句“selectidfromXXX”。首先通过词法分析,从左到右一个一个地分析字符,然后通过语法规则进行分析,判断输入的SQL语句是否满足MySQL语法,生成语法树,大概是这样的。小姐姐已经知道我们要做什么了。毕竟分析器小哥已经帮他分析过了,只是可能我们的语句不够漂亮,需要贴心的优化小姐姐来做优化。贴心小姐姐是怎么做到的?我们看到小姐姐先把SQL语法树拿出来,然后开始干活。不得不说小姐姐的作品真的很好看,那么具体是做什么的呢??看整个过程,我们看到她大概做了两件事。逻辑变化,成本优化,什么是逻辑变化?逻辑变换是在关系代数的基础上进行变换,其目的是简化和保证变换前后的SQL。结果是一致的,即逻辑上的变化不会带来结果集的变化。主要包括以下几个方面:否定剔除:对于“求和”或“析取”前出现“否定”的情况,对关系条件进行拆分,剔除外面的“NOT”。等价常数传递:利用等价关系的传递特性,为了尽快进行“下推”操作。“下推”的基本策略是始终将过滤器表达式移动到尽可能靠近数据源的位置。常量表达式计算:对于一个可以立即计算出结果的表达式,直接计算出结果,同时尽可能提前对结果和其他条件进行简化。总结起来就是替换和预处理。成本优化呢?成本优化用于确定每个表,是否根据条件应用索引,应用哪个索引,确定多表连接的顺序。为了完成成本优化,需要找到成本最低的解决方案。可以说我们要执行的查询都是通过成本优化计算出来的,最终得到最小成本的方案来执行。优化之后,接下来就是我们的执行器大哥了。至此,执行者大哥就可以执行了。当开始执行时,执行者小哥会一脸严肃的翻看自己的权限簿,查看我们是否有执行查询的权限。如果没有,他会直接告诉我们SELECTcommanddeniedtouser'root'@'localhost'fortable'XXX'如果验证通过,他会根据表中的引擎信息判断调用哪个引擎接口,比如SQL:select*fromXXXwhereid=1;假设“id”字段没有被索引,就会调用存储引擎从第一项开始查找。如果id为1,则返回结果集。如果没有找到,则检查下一行,重复上一步的操作,直到读取完毕。整张表还是找对应的记录。执行者还画了一个草图来解释他一贯的执行顺序。最后的查询命令到这里就结束了。大致介绍了查询请求的执行过程,介绍了连接器、查询缓存、分析器、优化器、执行器。兄弟之间的分工合作,最后,我们为即将消失的querycache的兄弟默哀三分钟……
