用了那么长时间的 MySQL,sql 语句相信早已烂熟于心, 于是, 我就试着去了解它的执行原理, 以下是我学习过程中的总结要点.
只要是 B/S 架构, 都是会有客户端与服务端, MySQL 也不例外.
首先客户端发出一个请求, 这个请求就是一个查询请求 (Select), 而它请求的对象就是服务端, 服务端是怎么处理这项查询功能的呢?
逻辑分层
首先可以把服务端想象成一个大的容器, 里面有四层结构, 当一个请求过来后, 将会执行这四层, 执行一遍后才会返回给我们想要的结果.
第一层 : 连接层
也就是说, 我们客户端发送一个 Select 是直接交给连接层来处理, 而它的作用就是提供与客户端连接的服务
连接层只是与客户端建立起连接, 并且拿到我们的请求 (Select), 但是它本身不做处理, 因为它只做连接, 那谁来处理呢? 接着往下走.
第二层: 服务层
服务层可以干两件事情:
1. 提供给用户各种可以使用的接口
比如说刚才的查询就是, 我们常见的 CRUD(增删改查) 操作都在这里, 连接层拿到这个 Select 直接了给了服务层, 这里除了给用户提供接口以外, 还提供了一个声称为 Sql 优化器的东西
2.Sql 优化器 (MySQL QUery Optimier)
当我们编写 Sql 语句执行时, 执行到这里后 (第二层), 优化器会觉得我写的 sql 语句性能不够好, 这个时候, 优化器会自己写一个等价于跟我写的执行后结果一致的 sql 语句进行代替, 这个等价写法就是通过这个优化器把你写的 sql 给优化了, 因为它觉得你写的性能太低了, 所以它就把你写的 sql 给优化了一下, 这个优化操作就是优化器干的事情;
很明显, 优化器可以将 sql 语句进行优化, 它是可以对性能产生一定的好处, 但是有弊端! 举个例子:
"当你自己优化时是 a, 但是实际执行并不是 a, 因为优化器会觉得你优化的还是不够好, 结果把 a 变成 b 了, 也就说, 我明明写的是 a, 但程序执行的是 b"
这会对我们开发过程造成混乱, 因为它已经被优化了. 你写的跟之前的已经不是一致的了
第三层: 引擎层
它提供了各种存储数据的方式, 常见的有: lnnoDB,MylSAM
重点区别:
lnnoDB [MySQL 默认] : 它在设计的时候, 它是事物优先 [适合高并发操作] 原理: 因为它是行锁, 我每一条数据都要锁, 锁的太多, 性能就降低了, 虽然性能降低了, 但是我适合高并发了, 就不容易出错了
MylSAM: 性能优先 原理: 因为它是表锁, 对于表里面的十条数据来说是不受影响的, 对十条锁一次就完了, 所以性能快
性能优先就很好理解了, 比如说一万条数据, 它处理的快一点, 效率会高一点
事物就是防止一些并发操作, 并发太大可能出错, 所以适合高并发操作
所以在做项目的时候, 建立数据库时, 如果性能优先, 就选择 MylSAM 引擎, 如果是高并发操作, 就选择 lnnoDB 引擎; 如何更换引擎我下面会讲
第四层: 存储层
这就很好理解了, 最终的数据在存储层里面存储
说完四层后, 我们来厘清思路
首先客户端发出一个 Select 操作 ---> 连接层接收后给服务层 ---> 服务层对你的查询进行一个优化, 并把优化结果给引擎层 ---> 选择当前数据库的引擎, 选完引擎后, 引擎将最终的数据交给了存储层 ---> 存储层, 用存储层来存数据
查看引擎
show engines; 查看 MySQL 所支持的所有引擎
执行结果:
yes 就是支持, 在 InnoDB 支持选项是 DEFAULT(默认) 也就说明, 当我们创建数据库的时候默认引擎就是 InnoDB
查看当前数据库使用的引擎
show variables like '%storage_engine%';
执行结果:
很显然, 我们目前用的就是 InnoDB
指定数据库对象的引擎
我现在创建一张表, 这个张表我不用 InnoDB, 用 MylSAM, 因为我想让它性能优先, 下面我就使用 MySQL 命令行进行创建表
1. 指定数据库指令: use 数据库名
2. 在指定的数据库中创建一张简单的表
- create table tb(
- id int (4),
- name varchar(5),
- primary key(id)
- )ENGINE=MyISAM;
执行结果:
表明创建成功, 并且该表的引擎是指定的我们手动指定的引擎, 而不是默认的.
来源: http://www.linuxidc.com/Linux/2019-03/157261.htm