InnoDB 索引组织表缓存
1、索引组织表定义安全
在InnoDB存储引擎中,表都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(index organized table IOT)。优化
在InnoDB存储引擎中,每张表都有个主键(Primary key),若是在建立表时没有地定义主键,则InnoDB存储引擎会选择表中符合条件的列去建立主键。spa
条件:设计
1. 首先判断表中是否有非空的惟一索引(Unique NOT NULL),若是有,则该列即为主键。指针
2. 若是不符合上述条件,InnoDB存储引擎自动建立一个6字节大小的指针。code
当表中存在多个非空的惟一索引的时候,InnoDB存储引擎会根据建表时所建立的第一个非空惟一索引做为主键。blog
2、案例索引
建立test表内存
CREATE TABLE test( a INT NOT NULL , b INT NULL , c INT NOT NULL , d INT NOT NULL , UNIQUE KEY(b) , UNIQUE KEY(d) , UNIQUE KEY(c) )
初始化数据
INSERT INTO test SELECT 1,2,3,4; INSERT INTO test SELECT 5,6,7,8;
经过如下语句能够判断表带主键值(_rowid为主键)
select *,_rowid from test;
虽然b字段索引的顺序在d以前,但因为b字段容许空值,因此依次往下排即选取d字段为主键。
ps,若是为联合索引,那么久无能为力了!
3、为何须要惟一主键呢?
主键(primary key) 一列(或一组列),其值可以惟一区分表中的每一个行。 惟一标识表中每行的这个列(或这组列)称为主键。没有主键,更新或删除表中特定行很困难,由于没有安全的方法保证只设计相关的行。简单的说主键的目的在于索引。
InnoDB引擎使用汇集索引,数据记录自己被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,所以每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,若是页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)。
1. 若是表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。以下图所示:
这样就会造成一个紧凑的索引结构,近似顺序填满。因为每次插入时也不须要移动已有数据,所以效率很高,也不会增长不少开销在维护索引上。
2. 若是使用非自增主键(若是身份证号或学号等),因为每次插入主键的值近似于随机,所以每次新纪录都要被插到现有索引页得中间。此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增长了不少开销,同时频繁的移动、分页操做形成了大量的碎片,获得了不够紧凑的索引结构,后续不得不经过OPTIMIZE TABLE来重建表并优化填充页面。
如有不恰当之处,还望指教,谢谢!
参考书籍:
[1]. MySQL技术内幕:InnoDB存储引擎