赞
踩
一张图说明 一条SQL查询语句的执行过程
一条sql语句从发送到数据库到它执行完成并返回结果,主要经历以下几个过程:
连接器->查询缓存(如果开启了查询缓存,则会经过这一步,但是大多数情况下都是不开启的,也不建议开启,MySQL 8.0之后也删除了这一块功能)->分析器->优化器->执行器
1. 连接器
首先我们要跟数据库建立连接,这个过程就是连接器来完成的,它主要负责与客户端的通信,验证用户名和密码是否正确等。大多数的应用系统会在第一次启动的时候建立好一定数量的数据库连接池,这个就是通过连接器与数据库提前建立好连接
2. 查询缓存
开启了查询缓存,那么在select查询语句过来的时候会先到查询缓存看看之前是不是执行过这条语句,查询缓存存储的数据是以键值对的形式进行存储(类似与map),key就是查询的sql语句,value是查询的结果。由于查询缓存这一块不是那么重要而且MySQL 8.0之后也删除了,这里就不再过多研究。面试的时候也只需要提一句即可。
3. 分析器
对客户端传来的 sql 进行分析,包括预处理与解析过程,并进行关键词的提取、解析,并组成一个解析树,主要提取如 select/update/delete/or/in/where/group by/having/count/limit等这样的关键词
select * from user where id = 1
例如这样的一条语句,在分析器中就通过语义规则器将select from where这些关键词提取和匹配出来,将用户的匹配字段和自定义语句识别出来,这个阶段也会做一些校验,比如校验user表是否存在,表中是否有id字段等
4. 优化器
经过前面的步骤,数据库已经知道SQL可以执行了,接下来优化器会根据执行计划选择最优的选择,匹配合适的索引,选择最佳的方案。
5. 执行器
执行器会调用对应的存储引擎执行 sql。主流的存储引擎是MyISAM 和 Innodb。
存储引擎就是为如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法
MyISAM:这种引擎是mysql最早提供的,不支持事务、不支持行级锁(支持表级锁)、不支持外键约束的功能
InnoDB:InnoDB 可以看作是对MyISAM的进一步更新产品,它提供了事务、行级锁机制和外键约束的功能(一般面试的时候会问MyISAM和InnoDB的区别,把上面两句话回答一下就差不多了)
memory:这种类型的数据只存在于内存中。它使用散列索引,所以数据的存取速度非常快。因为是存在于内存中,所以这种类型常应用于临时表中
archive:这种类型只支持select 和 insert语句,而且不支持索引。常应用于日志记录和聚合分析方面
redo log (重做日志) 作用:确保事务的持久性。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的持久性这一特性。
什么时候产生:事务开始之后就产生redo log,redo log的落盘并不是随着事务的提交才写入的,而是在事务的执行过程中,便开始写入redo log文件中
什么时候删除:当对应事务的脏页写入到磁盘之后,redo log的使命也就完成了,redo log占用的空间就可以被重用(被覆盖)
undo log(回滚日志) 作用:保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读
什么时候产生:事务开始之前,将当前数据的版本生成undo log,undo 也会产生 redo 来保证undo log的可靠性
什么时候删除:当事务提交之后,undo log并不能立马被删除,而是放入待清理的链表,由purge线程判断是否由其他事务在使用undo段中表的上一个事务之前的版本信息,决定是否可以清理undo log的日志空间
undo log 和redo log 主要用来保证事务相关操作,除此之外还有binlog(二进制日志,用于主从复制和基于时间点的还原等)、errorlog(错误日志)等
mysql脏页:当内存数据页和磁盘数据页上的内容不一致时,我们称这个内存页为脏页,内存数据写入磁盘后,内存页上的数据和磁盘页上的数据就一致了,我们称这个内存页为干净页。
刷脏页的时机:
考虑where和order等涉及的字段上建立索引,当然索引不是越多越好,建的多影响更新、插入性能。
字段已经有索引了,则需要避免索引失效,如:避免对索引字段进行计算操作(如num+1等),避免使用函数,避免索引字段使用not,<>,!=,IS NULL,IS NOT NULL,LIKE等,同时要注意索引字段的顺序,遵循最左匹配原则。
避免使用DISTINCT,order等耗资源的操作
select语句中避免使用select * from 使用明确的字段代替*号
多表关联查询时,数据量小的表在前,数据量大的表在后
针对复杂的SQL语句,考虑拆分成多个单条语句,在业务上处理
优化的建议有很多,这个过程也需要一个长期的积累。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。