这篇文章主要讲两个东西,第一个是mysql的执行流程,第二个讲一条mysql行记录的存储结构是怎样的。了解这两个问题,下次遇到面试官问,自然可以家里有粮,心中不慌。
当我们执行一条查询select,期间发生了什么执行一条SQL查询语句,期间发生了什么?这个需要我们了解mysql的整个内部结构。如下:
连接器:建立连接,管理连接、校验用户身份;
查询缓存:查询语句如果命中查询缓存则直接返回,否则继续往下执行。MySQL8.0已删除该模块;
解析SQL,通过解析器对SQL查询语句进行词法分析、语法分析,然后构建语法树,方便后续模块读取表名、字段、语句类型;
执行SQL:执行SQL共有三个阶段:
预处理阶段:检查表或字段是否存在;将select*中的*符号扩展为表上的所有列。
优化阶段:基于查询成本的考虑,选择查询成本最小的执行计划;
执行阶段:根据执行计划执行SQL查询语句,从存储引擎读取记录,返回给客户端;
文字总是枯燥的,一图胜千言。
mysql一条行的存储结构首先我们引入问题:
MySQL的NULL值会占用空间吗?怎么存储的?
MySQL怎么知道varchar(n)实际占用数据的大小?
varchar(n)中n最大取值为多少?
当我们知道mysql行的存储结构,自然这些问题也就迎刃而解。下面是mysql行的结构。
varchar怎么存储实际占用数据我们可以从行格式中会用「变长字段长度列表」存储变长字段实际占用的数据大小。
mysql如何存储null值MySQL的Compact行格式中会用「NULL值列表」来标记值为NULL的列,NULL值并不会存储在行格式中的真实数据部分。
NULL值列表会占用1字节空间,当表中所有字段都定义成NOTNULL,行格式中就不会有NULL值列表,这样可节省1字节的空间。
如果存在允许NULL值的列,则每个列对应一个二进制位(bit),二进制位按照列的顺序逆序排列。
二进制位的值为1时,代表该列的值为NULL。
二进制位的值为0时,代表该列的值不为NULL。