MySQL的btree索引和hash索引&聚集索引

1,BTREE是多叉树,多路径搜索树。有N棵子树的节点它包含N-1个关键字,例如,有3个子树的非叶子节点,那么就有2个关键字,每个关键字不保存数据,只用来存储索引(在索引存储数据时,将索引指向关键字的值也存储进来。最终实现key = &get; value结构)。所有的数据最终都要落在叶子节点,所有的叶子节点包括关键字信息以及指向这些关键字的指针,而且叶子节点是根据关键字大小、顺序链接的。所有的叶子节点都必须有个链表指针把数据串起来。所以,所有非叶子节点可以看成索引部分,包括子树中最大值或最小值关键字等信息。在btree索引下,获取数据时只需要从索引树的最小节点,一直不断的向右进行遍历就可以快速的得到想要的数据(这种遍历有指针把数据串起来),不需要回溯到根节点, 这样就可以理解为什么innodb的主键索引不能用离散的数据。

下图为2层btree结构:

2,哈希索引建立在哈希表的基础上,它对每个值采用精确查找。每一行都需要先计算哈希码,比较好的哈希算法算出比较低的重复的度,这样效率相对高一些。如果算出来的值是一样的,那么它需要再进行判断哪个值才是想要的值,所以说在表里面采用哈希索引,但是重复度又比较高,那么哈希索引效率就比较低。

HASH索引PK BTREE索引:大量不同数据等值精确查询,HASH索引效率通常比BTREE高;HASH索引不支持联合索引的最左匹配规则(where a =? and  b=? ,index(a,b,c)这样无法同时使用a,b,c,相当于是范围查询);HASH索引不支持排序;HASH索引不支持模糊查找;

下图为哈希索引:

3,聚集索引,其实就是索引的组织方式,整个表存储的逻辑顺序根聚集索引的顺序是一致的,也就是说聚集索引决定了整个表的物理的存储的逻辑顺序。mysql一个表只支持一个聚集索引。在innodb里面聚集索引就是整个表,表就是聚集索引,因为innodb的聚集索引后面是整行数据,在聚集索引btree里面每个叶子节点最终存储每行数据,这就是为什么在innodb里面没有任何条件count (*),它会优先选择普通索引来完成扫描,而不是采用主键索引,因为如果扫聚集索引,扫描的数据量更大,产生的IO更大,如果扫描普通辅助索引,那么它的数据结构通常来讲比主键索引小。

innodb的普通索引叶子节点里面存储着主键索引的键值。聚集索引决定了物理表的存储顺序,如果聚集索引频繁修改,可能会导致修改存储的顺序,那么这个行数据会产生位移,产生数据离散IO。如果新增的数据太过离散,也会导致聚集索引存储的位置相应的离散,也会导致随机IO.

聚集索引的选择:

a,含有大量非重复值的列;

b,被连续(顺序)访问的列;

c,返回大量结果集的查询;

案例:

如果一个表很大,有1/3数据要删除,如果是随机删除,会产很多空洞,删完后产生的空洞不写入,没什么影响,但这种删除比较慢,因为需要对btree进行随机扫描。删完后索引树会进行自旋,如果它的page填充因子比较低,例如把2页合并成1页,在合并中进行写入会比较慢。 删完后可以执行alter  table engine=innodb 来整理碎片,但是会锁表。建议使用pt-osc来完成表空间回收。

时间: 2024-11-08 20:25:07

MySQL的btree索引和hash索引&聚集索引的相关文章

蛋疼的郁闷——聚集索引扫描、非聚集索引扫描、表扫描区别

聚集索引扫描,首先我们知道数据它是以索引键为叶节点排列起来的树形数据结构,表中每行的数据都附属在索引键中,对这样的表进行数据查找时,最快的方式当然是“聚集索引查找”.什么情况下才是“聚集索引扫描”呢?是当你要查找的数据的条件字段上没有索引时,此时查询执行器将对整个表中的数据挨个的进行读取确认符合查询条件的数据,但当该表上有字段设有聚集索引时,该扫描过程称之为“聚集索引扫描",相反的情况是当该表上没有一个字段设有”聚集索引“时,该扫描过程称之为”表扫描“.其实他们本质上的过程都是一样的,就是挨个的

索引深入浅出:非聚集索引的B树结构在聚集表

一个表只能有一个聚集索引,数据行以此聚集索引的顺序进行存储,一个表却能有多个非聚集索引.我们已经讨论了聚集索引的结构,这篇我们会看下非聚集索引结构. 非聚集索引的逻辑呈现 简单来说,非聚集索引是表的子集.当我们定义了一个非聚集索引时,SQL Server把整套非聚集索引键存在不同的页里.我们来看下一个包含BusinessEntityID(PK),PersonType,FirstName,LastName这4列的表,这个表上有一个非聚集索引定义.主体表按BusinessEntityID列(聚集索引

蛋疼的郁闷-聚集索引扫描、非聚集索引扫描、表扫描区别

本文适用于对数据库索引有一定深入的攻城师阅读参考. 我们对于聚集索引扫描和表扫描比较容易理解的,但是对于非聚集索引扫描不太容易理解,这一点也往往容易使初学者感到很是困惑,原因是总认为没必要存在非聚集索引扫描,因为如果查询结果不具有高选择性的话,在聚集索引表中可以使用聚集索引扫描,在对表中会使用表扫描的,那么为什么要会存在非聚集索引扫描呢? 之所以有这样的问题,是因为我们没有考虑到一种情况,那就是查询结果如果被建有非聚集索引的字段覆盖或包含了,而此时where条件字段上的非聚集索引对于本次查询结果

SQL Server索引 (原理、存储)聚集索引、非聚集索引、堆 <第一篇>

一.存储结构 在SQL Server中,有许多不同的可用排列规则选项. 二进制:按字符的数字表示形式排序(ASCII码中,用数字32表示空格,用68表示字母"D").因为所有内容都表示为数字,所以处理起来速度最快,遗憾的是,它并不总是如人们所想象,在WHERE子句中进行比较时,使用该选项会造成严重的混乱. 字典顺序:这种排序方式与在字典中看到的排序方式一样,但是少有不同,可以设置大量不同的额外选项来决定是否区分大小写.音调和字符集. 1.平衡树(B-树) 平衡树或B-树仅是提供了一种以

索引深入浅出:非聚集索引的B树结构在堆表

在“索引深入浅出:非聚集索引的B树结构在聚集表”里,我们讨论了在聚集表上的非聚集索引,这篇文章我们讨论下在堆表上的非聚集索引. 非聚集索引可以在聚集表或堆表上创建.当我们在聚集表上创建非聚集索引时,聚集索引键担当为行指针.在堆表里,文件号,页号和槽号(file id , page number and slot number)的组合在非聚集索引里担当为行指针. 我们来看下手头的一个例子.我们创建salesorderdetail表的副本,并在上面的productid和salesorderid 列创

mysql在B-Tree上创建伪哈希索引

构建哈希的过程 select过程 长字符串下,构建索引可通过自定义哈希作为索引,本人通过实验,在3百多个数据记录的下,性能效果很明显,完全不是一个等级.以下为索引前后几种情况对比 无索引的url:直接通过无索引url 通过构建url的哈希索引:用bigint类型存储索引字段crc_url 在哈希索引下,几乎都是0秒完成. 当然,如果直接使用url作为索引,即用B-Tree存储url存储的内容会很大. 题外话: 在where字句中,优化器会根据查询条件是否存在索引,优先进行索引查询. 如下为例子:

Mysql聚集索引的使用

聚集索引 聚簇索引并不是一种单独的索引类型,而是一种数据存储方式(不是数据结构,而是存储结构),具体细节依赖于其实现方式,聚簇索引实际上是在同一个结构中保存了btree索引和数据行. innodb将通过主键聚集数据,如果没有定义主键,Innodb会选择第一个非空的唯一索引代替,如果没有非空唯一索引,Innodb会隐式定义一个6字节的rowid主键来作为聚集索引 叶子页包含了行的全部数据,但是节点页只包含了索引列(或者可以说非叶子节点的节点页包含的是索引值的索引,因为这些节点页包含的值是从索引列中

聚集索引

转自:mysql索引之聚集索引 聚集索引不是一种单独的索引类型,而是一种存储数据方式.其具体细节依赖于实现方式,但是InnoDB的聚集索引实际上在同样的结构中保存了B-Tree索引和数据行. 当表有聚集索引的时候,它的数据行实际保存在索引的叶子页中.术语“聚集”指实际的数据行和相关的键值都保存在一起.每个表只能有一个聚集索引,因为不能一次把行保存在两个地方.(但是,覆盖索引可以模拟多个聚集索引) 当前,SolidDB和InnoDB是唯一支持聚集索引的存储引擎.InnoDB按照主键进行聚集,如果没

主键,组合主键,聚集索引,非聚集索引,唯一索引

前言: 基于Oracle数据库谈谈索引们的问题,以及在什么情况下使用什么索引, 组合主键,怎么根据实际业务需求来定制自己的索引,主键的应用,来提升系统的性能. 1:主键? 在表中唯一的,也是聚集索引.作用于快速查询.该列唯一. Java代码 复制代码 收藏代码 1.ID NUMBER(38,0) PRIMARY KEY NOT NULL, 2:组合主键? 在表中以多个字段组成在表中是唯一的,也是聚集索引.作用于快速查询.该组合列唯一. Java代码 复制代码 收藏代码 1.CREATE TABL