说一说执行一条SQL语句的执行过程
×
第一步,连接器负责连接、用户检验、接受SQL语句。
第二步,查询缓存,如果查询到缓存直接返回,否则继续查询。但是在8.0之后,缓存功能就删除了,因为在实际的场景中缓存命中率不高。
第三步,解析器对SQL语句进行语法和词法分析,构建语法树,方便后续模块读取表明、字段、语句类型。
第四步,优化器会基于查询成本的考虑,判断每个索引的执行成本,从中选择查询成本最小的执行计划。
第五步,执行器会根据执行计划来执行查询语句,从存储引擎读取记录,返回给客户端。
MySQL存储引擎有哪些?
MySQL常见的存储引擎有InnoDB、MyISAM、Memory
其中,InnoDB是MySQL默认的存储引擎,支持事务和行级锁。
MyISAM引擎是不支持事务和行级锁的,而且由于只支持表锁,更新性能比较差,比较适合读多写少的场景。
Memory引擎是将数据存储在内存中,所以数据的读写比较快,但是数据不具备持久性,适用于临时存储数据的场景。
InnoDB和MyISAM在数据存储上也有很大的区别,InnoDB是将表数据和索引数据存放在同一个文件的,而MyISAM是将表数据和索引数据分开存储的,所以,InnoDB引擎B+树索引中的叶子结点存储的是索引和数据,MyISAM引擎B+树索引中的叶子结点存储的是索引和数据地址。
null 值是如何存储的?
MySQL行个数中会用null值列表来标记为NULL的列,每个列对应一个二进制位,如果列的值为null,就会标记二进制位为1,否则为0,所以NULL值并不会存储在行格式中的真实数据部分。
null值列表最少会占用1字节空间,当表中所有列都定义为NOT NULL,行个数中就不会有NULL值列表,这样就可以至少节约1字节的空间。
char 和 varchar 有什么区别?
char 是固定长度的字符串类型,它在数据库中占用固定的存储空间,无论实际存储的数据长度是多少,都会占用定义时指定的固定长度,如果实际存储的字符长度小于定义的长度,系统会自动填充为空格。
varchar是可变长度的字符串类型,实际存储时只占用实际字符串长度的空间,不会进行空格填充。比如varchar(10)在内存中占用10字节,文件存储空间会占用6字节,并且还会额外用1-2字节存储[可变长字符串长度]的空间。
如果硬件内存特别大,MySQL缓存能否代替redis?
MySQL缓存是不能替代redis的。
首先MySQL的所有模块都是面向磁盘页面设计的,因此其首要目标不是减少内存访问的代价,而是I/O代价,而redis是面向内存而设计的数据库。
MySQL在内存查询一个数据页的时候,都需要先查页表,也就是需要走b+树的搜索过程,时间复杂度是O(logN),而Redis提供了很多数据类型,它们的查询过程都可达到O(1)。