执行一条Sql请求的过程是什么?
- 1、连接器:建立连接,管理连接、校验用户身份。
- 2、查询缓存:查询语句如果直接命中缓存则会直接返回,否则继续往下执行。MySql8.0已移除该模块。原因:查询数据的频繁更新会导致缓存频繁失效,缓存命中率低,且内存占用高。
- 3、解析Sql:解析器会对sql语句的语法、词法进行解析,然后构建语法树,方便后续模块读取表名、字段、语句类型。
语法树的结构:
根结点:代表整个sql语句
内部节点:代表语法单元(如select、from、where子句)
叶子节点:存储基本元素(如列名、表名、常量)
语法树示例:
SELECT name, age FROM students WHERE age > 18
Query
├─ SelectClause
│ ├─ ColumnRef(name)
│ └─ ColumnRef(age)
├─ FromClause
│ └─ TableRef(students)
└─ WhereClause
└─ BinaryOp(>)
├─ ColumnRef(age)
└─ Value(18)
- 4、执行sql:
- 预处理阶段:检查表或字段是否存在,将*扩展为所有字段
- 优化阶段:基于查询成本,选择查询成本最小的执行计划(如使用索引)
- 执行阶段:根据执行计划查询sql语句,从存储引擎读取记录,返回给客户端
MySQL的引擎有哪些?
InnoDB:默认引擎,支持ACID事务,行级锁、外键约束等特性,适用于高并发的读写操作,支持较好的数据完整性和并发控制。
MyISAM:具有较低的存储空间和内存消耗,写开销大:写入时需同步更新索引的指针和数据,适用于大量读的场景。但不支持事务、行级锁和外键约束,因此在并发写入和数据完整性有一定限制。
Memory:将数据存储在内存中,适用于性能较高的读写操作,但不支持事务、行级锁及外键约束,且服务器重启或崩溃时会丢失所有数据。
为什么默认使用InnoDB?
- 1、事务支持:InnoDB提供了对事物的支持,可以进行ACID属性的操作。MyISAM是不支持事务的。
- 2、并发性能:InnoDB采用的是行级锁,可以提供更好的并发性能,MyISAM存储引擎只支持表锁,锁粒度比较大。
- 3、崩溃恢复:InnoDB引擎通过redolog日志实现了崩溃恢复,可以在数据库发生异常状况时通过日志文件进行恢复,保证数据的持久性和一致性。MyISAM不支持崩溃恢复。
MyISAM与InnoDB的区别:
- 1、事务:InnoDB支持事务,MyISAM不支持事务。
- 2、索引结构:InnoDB是聚簇索引,MyISAM是非聚簇索引。InnoDB中默认主键索引为聚簇索引,没有主键时会寻找第一个唯一非空索引作为主键索引,或隐式创建一个自增主键。聚簇索引的叶子节点存放完整数据。而MyISAM是非聚簇索引,叶子节点并不直接存放完整数据,而是存放数据指针。
特性 |
非聚簇索引 |
聚簇索引 |
数据存储 |
数据行按插入顺序保存 |
数据按主键排序存储 |
索引存储内容 |
键值+数据行地址 |
键值+完整数据行 |
回表操作 |
无需回表,每个索引都直接存储指针 |
辅助索引存储主键,需回表查询 |
主键要求 |
可以没有主键 |
必须有主键(或隐式主键) |
- 3、锁粒度:InnoDB最小的锁粒度是行锁,MyISAM最小的锁粒度是表锁。写操作时会锁住整张表,导致其他查询和更新语句阻塞。
- 4、count的效率:InnoDB不保存表的具体行数,执行select count(*)时需要进行全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快。