MYSQL

MySQL的逻辑结构

客户端+服务器+存储引擎

MYSQL

存储引擎

查看存储引擎: show engines.我的电脑里默认的是InnoDB;

InnoDB和MyISAM索引采用的是B+树, MEMORY采用的是Hash索引.

MySql中最常用的的存储引擎是InnoDB和MyISAM.

前者在磁盘中会落2个文件,分别是.frm和.ibd..frm代表form files,代表格式文件..ibd中包含真实数据和索引数据.

而myISAM中会落3个文件,分别是.frm,.MYD和.MYI,其中后面两种格式代表真实数据和索引数据.

MYSQL

MYSQL

内存和磁盘交互:

MYSQL

  磁盘预读:预读的长度一般是页的整数倍.页是存储器(包括内存和磁盘)的逻辑块,通常为4KB,内存和磁盘以页来为单位交换数据.InnoDB默认一次预读16KB的数据.

索引:

为什么要创建索引:

如果没有索引,查找数据是全表扫描,而如果有索引的话,会按照B+树的结构去查找数据.

创建索引是个什么过程?

就是把数据组织成数据结构的过程.

存储在文件系统中,存储形式和存储引擎有关,索引文件的结构包括hash,二叉树,B树和B+树.

hash表:是数组+链表的结构.

hash作为索引存在的问题 :

1.哈希函数不容易选择

2.hash存储需要将所有的数据文件添加到内存(why?待后知后觉),浪费内存空间.

3.等值查询用hash比较快,但是实际中范围查询更多,hash不太合适.

以上问题使得hash没有作为大部分存储引擎(查找数据是与磁盘进行交互)的数据结构.而MEMORY存储引擎是在内存中进行的,使用它的时候就接受它占内存的问题了,另外在内存中查找速度很快.

二叉树,红黑树存在的问题:

树中元素存储的是数据值,树在物理结构上是数组进行存放的,可能逻辑结构上很近的数据(比如父子)在物理结构上会相差很远(比如当树很大时).因此,每次读取磁盘页的数据很多是用不上的.可能需要进行很多次的IO交互才能够找到要找的数据.

都会因为树的深度太深而造成io次数变多(指的是内存和磁盘交互的次数),影响读取的效率.

 

提升IO效率的两个方法:

1.减少IO的次数

2.减少IO的大小

eg:不推荐使用select(*)的原因,是因为它会把磁盘中全表的数据都拉到内存(mysql的服务)中,然后在内存中去进行筛选,筛选完毕后给到客户端中.

B树:

树中节点存储的是数据块.

图中紫色的代表键值,它可能是记录的主键.

树的阶数(degree)等于它可以最多存储指针的个数(数据的个数比指针个数少1).

比如下面的这个示意图,它最多能够存3个指针,两个data,它的degree是3.

假如当前磁盘块的大小为16KB,每个data占1KB的内存,忽略键值和指针,一个磁盘块中可以存16个data,即阶为17.那么三层树可以存储的数据量16+17*16+17*17*16=16*(1+17+17*17)=4912条数据.从这里可以看出来影响存储数据多少的因素是data的大小,而这个时候B+树就比较合适了.

MYSQL

 B+树:

同样的3层树,如果前两层只存储键值和指针的话,那么对应存储的指针数就会大大增加,假如前两层每个磁盘可以存储1600个指针,第三层仍然是存储16个数据,那么三层树总共可以存储的数据量=1600*1600*16 = 40960000,差不多数据容量增加了1万倍.

注意这里为什么特别在意树的层数呢?因为树的层数越深,查找树的次数就越多(最坏情况,单枝退化成了链表).

B+树中有两种查找方式:一种是对于主键的范围查找和分页查找,另一种是从根节点开始,进行随机查找.

MYSQL

InnoDB和MyISAM所以创建的区别:

InnoDB,叶子节点中放置的是数据,对应.ibd,<-> 聚簇/聚集索引.

MYSQL

注意:

1.InnoDB对主键创建索引,也就是把主键作为B+树中的Key,如果没有主键,会选择唯一键,如果没有唯一键,会生成一个6字节的row_id(不可见)来作为主键(都是为了保证key的唯一性).

2.如果创建索引的键是其他字段,那么在叶子节点中存储的是该记录的主键,然后再通过主键索引找到对应的记录,这个过程叫做回表.

比如下图中又对表中的name建立了索引(称为二级索引/辅助索引),如果要执行select * from table where name = "ma",根据"ma"找到了主键1,这个时候还需要根据主键回到表中查找所有的列.而如果select id from table where name = "ma"的话,则不会触发回表.

MYSQL

MyISAM中叶子节点冲存储的是地址,然后根据地址去查找数据.所以存储文件是.MYI,.MYD. <->非聚簇索引.

 MYSQL

 MySQL的B+树三层还是四层,取决于数据量的多少.

主键自增:

分布式不推荐(分布式中有自己的主键生成策略),

非分布式推荐.

主键自增,能够保证后面插入的数据在建立索引时从添加到树的结尾.如果主键是乱序的话,在创建索引时,会插入到中间位置.如果中间位置满了,会导致页分裂,会造成维护上很麻烦.(添加到结尾,如果数据满了也会造成页分裂,但没有中间插入的那种情况严重).

索引优化相关:

1.尽量用int来存储索引,它只占4个字节,而varchar会占用比较多的字节.

2.

相关推荐