赞
踩
位于最上层的客户端服务,包括连接处理、身份验证等功能,支持多种服务端语言,通过 API 接口与 MySQL 建立连接。
MySQL 的核心功能都在这一层,包括查询解析、分析、优化,以及所有的内置函数(例如:日期、数学函数),所有跨存储引擎的功能也都在这一层实现:存储过程、触发器、视图等。
1.2.1.连接管理:
每个客户端连接都会在服务器进程中拥有一个线程,该连接的查询只会在这个单独的线程中执行,该进程驻留在内核或者 CPU 上。服务器维护了一个缓冲区,作为连接池,存储已就绪的线程。
1.2.2.优化与执行:
MySQL 解析查询以创建解析树,然后对其进行各种优化,包括重写查询,决定表的读取顺序,以及选择合适的索引等。
存储引擎负责 MySQL 中数据的存储和提取,服务器通过存储引擎 API 进行通信。这些 API 屏蔽了不同存储引擎之间的差异,使得它们对上面的查询层基本上是透明的。最常用的存储引擎是 InnoDB。
1.4.1.binlog
1.4…2.redo log
1.4…3.undo log
整数的类型有:TINYINT、SMALLINT、MEDIUMINT、INT 和 BIGINT,分别使用 8、16、24、32、和 64 位存储空间,可以存储的值的范围从 -2 的(n-1)次方到 2 的(n-1)次方-1,其中 n 是存储空间的位数。
整数类型有可选的 UNSIGNED 属性,表示不允许负值,大致上可以使正整数的上限提高一倍。
MySQL 可以为整数类型指定宽度,只是规定了 MySQL 的客户端显示字符的个数,不会限制值的合法范围。
实数是带有小数部分的数字。也可以使用 DECIMAL 存储比 BIGINT 还大的整数,MySQL 既支持精确类型,也支持不精确类型。
FLOAT 和 DOUBLE 类型支持使用标准的浮点运算进行近似计算。FLOAT 列使用 4 字节的存储空间,DOUBLE 占用 8 字节。
DECIMAL 需要额外的存储空间和计算成本,尽量在对小数需要进行精确计算时进行使用,例如:存储财务数据。在一些大容量的场景,可以考虑使用 BIGINT 代替 DECIMAL,将需要存储的货币单位根据小数的位数乘以相应的倍数即可,可以避免浮点存储计算不精确和 DECIMAL 精确计算代价高的问题。
VARCHAR:
CHAR:
BLOB 和 TEXT 类型:
DATETIME:
TIMESTAMP:
BIT:
IP:
如何在不影响数据库或者依赖它们的服务正常运行的情况下,进行 schema 的变更?
原生 DDL 语句:
MySQL 在 5.6 版本中引入了非阻塞的 schema 更改,对原生 DDL 的支持有限,在需要更改的表非常大时,可能会遇到回滚的情况。
外部的工具:
主要选择有 Percona 的 pt-online-schema-change 和 Github 的 gh-ost。实现原理是对正在更改的表进行完整的复制,执行完表结构变更,再把源表的全量数据和增量数据同步过去,最后进行表替换。
索引是存储引擎用于快速找到记录的一种数据结构。
B-tree 索引:
自适应哈希索引:
InnoDB 存储引擎在发现某些索引值访问非常频繁时,会在原有 B-tree 索引之上,在内存中在构建一个哈希索引;
全文索引:
FULLTEXT 是一种特殊类型的索引,查找的是文本中的关键字,类似于搜索引擎;
适用的查询类型:
索引排序:
索引的限制:
前缀索引:
索引的选择性:
是指不重复的值(也称之为基数)和数据表的总记录数(T)的比值,范围是 1/T 到 1 之间;索引的选择性越高则查询效率越高。
如何确定前缀索引的长度?
前缀索引的长度,既要足够长来保证较高的选择性,又不能太长(节省空间);
可以通过计算不同长度前缀和完整列,与总行数的比率,使用较接近的长度前缀;
多列索引:
索引的常见误区是为每列创建独立的索引,或者按照错误的顺序创建多列索引。
如何选择合适的索引列顺序:
根据经验法则:将选择性最高的列放到索引的最前列,在大部分场景下是有效的。
但是索引性能不仅仅依赖于选择性,和查询条件的具体值,以及值的分布都有关,此时可以根据运行频率最高的查询来适当调整索引列的顺序。
聚簇索引:
聚簇索引是一种数据存储方式,InnoDB 的聚簇索引是在同一个结构中保存了 B-tree 索引和数据行。InnoDB 根据主键聚簇数据,如果没有定义主键,会选择唯一的非空索引代替,次之会隐式定义一个主键。
按主键顺序插入行:
如果 InnoDB 表中没有数据需要聚集,可以使用一个代理键来作为主键(例如 AUTO_INCREMENT 自增列),以保证数据行是按顺序写入的,来提升性能。
随机的聚簇索引,例如 UUID 会使得数据没有任何聚集特性,插入也变得完全随机,应该尽量避免。
覆盖索引:
如果一个索引包含所有需要查询的字段的值,称之为覆盖索引。不需要回表查询,效率更高。
使用索引来排序:
只有当使用的顺序和 ORDER BY 子句的顺序完全一致,并且所有列的排序方向(顺序或者倒序)都一样时,MySQL 才能使用索引对结果进行排序。
在 EXPLAIN 的输出结果中,type 列的值为”index”,说明 MySQL 使用了索引扫描来进行排序。
查询的生命周期,大致上可以分为:客户端连接到服务端,服务端进行语法解析,生成执行计划,执行,并给客户端返回结果。
其中“执行”阶段是整个生命周期中最重要的阶段,包括大量为了检索数据对存储引擎的调用,以及调用后的数据处理(排序、分组等)。
查询的数据是否过多:
MySQL 是否在扫描额外的记录:
在不能使用索引生成排序结果的时候,MySQL 需要自己继续排序,数据量小则在内存中进行,数据量大则需要使用磁盘,在 MySQL 中统称文件排序。
排序的具体实现:
如果需要排序的数据量小于“排序缓存区”,MySQL 使用内存进行快速排序操作,如果内存不够排序,那么 MySQL 会先将数据分块,对每个独立的块使用快速排序,并将各个块的排序结果存放在磁盘上,然后将各个排好序的块进行合并,最后返回排序结果。
在 MySQL 的 EXPLAIN 结果的 Extra 字段可以看到“Using temporary; Using filesort”字样,说明使用了临时表、文件进行排序。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。