前言
作为一个开发,避免不了和数据库打交道,尤其是 mysql。往往只会用,但是没有去探究其 一条 sql 语句具体是怎么样去实现的,以及 mysql 的基础架构,接下来将记录在学习mysql 中的一些要点。
mysql 基础架构
mysql 主要分为 server 层 和 存储引擎层。
server 层 主要连接器、查询缓存、分析器、优化器、执行器等
- 连接器 : 管理连接,权限校验
- 分析器:词法和语法分析
- 优化器:执行计划生成,索引选择
- 执行器:操作引擎,返回结果
- 查询缓存:命中直接返回结果
存储引擎
- InnoDB
- MyISAM
- Memory 等
从 mysql 5.5.5版本 开始默认使用 InnoDB 引擎。
连接器
mysql -h$ip -P$port -u$user -p
可以将密码直接敲上去,但是在生产环境中还是不建议这样,采用上边交互的方式输入密码,比较安全。
可以使用 show processlist 来查看数据库的连接状态。
其中 Command 为 Sleep 的表示其为空闲连接。
如果客户端太长时间没有动静,连接器就会自动将其断开,这个时间由参数 **wait_timeout
** 来空值,默认是 8 小时。
在之前一次项目开发中,由于数据源配置参数不对,导致与数据库的连接一直空闲没有释放,但是mysql服务端因为默认8小时已经断开此连接,当后端客户端再次请求时,以为这个连接还没断开,再次请求就会发现没有响应的情况。
在于数据库交互的时候,我们通常都会使用数据源,例如 c3p0,dbcp,druid 等,以及现在 springboot 2.x 默认的 HikariCP等,是因为与数据库建立链接是一个十分耗费资源的事情。但是每次查询都要建立一次长链接,那么mysql很快就会oom。
所以要使用数据源连接池,其实现了:
-
定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开连接,之后要查询再重连。
-
如果你用的是 MySQL 5.7 或更新版本,可以在每次执行一个比较大的操作后,通过执行 mysql_reset_connection 来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。
查询缓存
建议不要使用此功能
如果非要使用,可以在 sql 语句中添加:
mysql> select SQL_CACHE * from table_name;
分析器
分析器就负责分析你的语句是否有语法错误
优化器
确定sql语句的优化方案,并确定使用哪个索引。
执行器
开始执行语句,但是在执行之前会校验你的权限。
如果表 T 中没有字段 k,而你执行了这个语句 select * from T where k=1, 那肯定是会报“不存在这个列”的错误: “Unknown column ‘k’ in ‘where clause’”。你觉得这个错误是在我们上面提到的哪个阶段报出来的呢?
分析器,在分析阶段,会判断语法是否正确以及表是否存在,列是否存在。