myisam使用的堆组织表(Heap Organize Table, HOT),没有聚集索引的概念,使用B-tree索引的存储格式,显示都是随机顺序。
innodb表是索引组织表(Index Organized Table, IOT),它的索引则是采用 clustered index 方式,因此主键会按照顺序存储,每次有记录有更新时,会重新整理更新其主键。因此无论是直接从 myisam 表转换过来的,还是后来插入的记录,显示时都会按照主键的顺序。
堆表(heap table)数据插入时时存储位置是随机的,主要是数据库内部块的空闲情况决定,获取数据是按照命中率计算,全表扫表时不见得先插入的数据先查到。
索引表(iot)数据存储是把表按照索引的方式存储的,数据是有序的,数据的位置是预先定好的,与插入的顺序没有关系。
索引表的查询效率比堆表高(相当于查询索引的效率),插入数据的速度比堆表慢。
索引表适用场景:
适用于信息检索、空间和OLAP程序。
1、 代码查找表。
2、 经常通过主码访问的表。
3、 构建自己的索引结构。
4、 加强数据的共同定位,要数据按特定顺序物理存储。
5、 经常用between…and…对主码或唯一码进行查询。数据物理上分类查询。如一张订单表,按日期装载数据,想查单个客户不同时期的订货和统计情况。
常用数据库支持情况:
Oracle支持堆表,也支持索引组织表
PostgreSQL只支持堆表,不支持索引组织表
Innodb只支持索引组织表
补充:(来自另一文)
堆表(heap table) 就是一般的表,获取表中的数据是按命中率来得到的。没有明确的先后之分,在进行全表扫描的时候,并不是先插入的数据就先获取。数据的存放也是随机的,当然根据可用空闲的空间来决定。
而iot就是类似一个全是索引的表,表中的所有字段都放在索引上,所以就等于是约定了数据存放的时候是按照严格规定的,在数据插入以前其实就已经确定了其位置,所以不管插入的先后顺序,它在那个物理上的那个位置与插入的先后顺序无关。这样在进行查询的时候就可以少访问很多blocks,但是插入的时候,速度就比普通的表要慢一些。
OT表相比HOT表的优势是:
1).范围查询效率更高;
2).数据频繁更新(聚集索引本身不更新)时,更不容易产生碎片;
3).特别适合有一小部分热点数据频繁读写的场景;
4).通过主键访问数据时快速可达;
IOT表的不足则有:
数据变化如果是离散为主的话,那么效率会比HOT表差;
HOT表的不足有:
1).索引回表读开销很大;
2).大部分数据读取时随机的,无法保证被顺序读取,开销大;
3).每张InnoDB表只能创建一个聚集索引,聚集索引可以由一列或多列组成。
上面说过,InnoDB是聚集索引组织表,它的聚集索引选择规则是这样的:
1).首先选择显式定义的主键索引做为聚集索引;
2).如果没有,则选择第一个不允许NULL的唯一索引;
3).还是没有的话,就采用InnoDB引擎内置的ROWID作为聚集索引;
所以,对于 聚集索引 来说,你创建主键的时候,自动就创建了主键的聚集索引。出了主键的聚集索引,其他索引(普通索引)中不会保存行的物理位置,而是保存主键的值,所以通过”二级索引”进行查找是先找到主键,再找到行,要进行二次索引查找。
3.聚集索引和非聚集索引的区别及优缺点:
区别:
1).聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个
2).聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续
3).聚集索引:物理存储按照索引排序;聚集索引是一种索引组织形式,索引的键值逻辑顺序决定了表数据行的物理存储顺序
非聚集索引:物理存储不按照索引排序;非聚集索引则就是普通索引了,仅仅只是对数据列创建相应的索引,不影响整个表的物理存储顺序.
4).索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。
优势与缺点:
聚集索引插入数据时速度要慢(时间花费在“物理存储的排序”上,也就是首先要找到位置然后插入),查询数据比非聚集数据的速度快