携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情
索引概述
索引是数据库优化最常用也是最重要的手段之一,通过索引通常可以帮助用户解决大多数的数据库的性能优化问题。 如下面的示意图所示:
左边是数据表,一共有两列七条记录,最左边的是数据记录的物理地址(注意逻辑上相邻的记录在磁盘上也并不是一定物理相邻的)。为了加快Col的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和—个指向对应数据记录物理地址的指针,这样就可以运用二叉查找快速获取到相应数据。
一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上。索引是数据库中用来提高性能的最常用的工具。
索引的优势劣势
优势
- 类似于书籍的目录索引,提高数据检索的效率,降低数据库的IO成本。
- 通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗。
劣势
- 实际上索引也是一张表,该表中保存了主键与索引字段,并指向实体类的记录,所以索引列也是要占用空间的。
- 虽然索引大大提高了查询效率,同时却也降低更新表的速度,如对表进行 INSERT、 UPDATE、 DELETE。因为更新表时,MSQL不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段,都会调整因为更新所带来的键值变化后的索引信息。
索引结构
按数据唯一性区分:“唯一索引”,“非唯一索引”
按键列个数区分:“单列索引”,“多列索引”
从存储结构上来划分:B-Tree,B+Tree,Hash索引
从应用层来分:普通索引,唯一索引,复合索引
从数据的物理顺序与键值的逻辑(索引)顺序关系分:聚集索引,非聚集索引
hash索引 类似于hashmap 索引列hash码,数据行指针---》hash冲突的话,链表,好处hash冲突低查询快,坏处无法排序只能精准条件查询,占内存。
b tree,多路平衡树,多路解决数层级太多,平衡为了解决树结构成为单条链表 B 树节点中不仅存储键值,也会存储数据,会导致每层阶数变少。 一般根节点都是常驻内存的,数据大的话层数多io就多
B+ tree 非叶子节点上是不存储数据的,仅存储键值,之所以这么做是因为在数据库中页的大小是固定的,InnoDB 中页的默认大小是 16KB。 如果不存储数据,那么就会存储更多的键值,相应的树的阶数(节点的子节点树)就会更大,树就会更矮更胖, 如此一来我们查找数据进行磁盘的 IO 次数又会再次减少,数据查询的效率也会更快。因为 B+ 树索引的所有数据均存储在叶子节点,而且数据是按照顺序排列的。 那么 B+ 树使得范围查找,排序查找,分组查找以及去重查找变得异常简单。而 B 树因为数据分散在各个节点,要实现这一点是很不容易的。 有心的读者可能还发现上图 B+ 树中各个页之间是通过双向链表连接的,叶子节点中的数据是通过单向链表连接的。
聚集索引(聚簇索引):以 InnoDB 作为存储引擎的表,表中的数据都会有一个主键,即使你不创建主键,系统也会帮你创建一个隐式的主键。 这是因为 InnoDB 是把数据存放在 B+ 树中的,而 B+ 树的键值就是主键,在 B+ 树的叶子节点中,存储了表中所有的数据。 这种以主键作为 B+ 树索引的键值而构建的 B+ 树索引,我们称之为聚集索引。
非聚集索引(非聚簇索引):以主键以外的列值作为键值构建的 B+ 树索引,我们称之为非聚集索引。 非聚集索引与聚集索引的区别在于非聚集索引的叶子节点不存储表中的数据,而是存储该列对应的主键,想要查找数据我们还需要根据主键再去聚集索引中进行查找,这个再根据聚集索引查找数据的过程,我们称为回表。 明白了聚集索引和非聚集索引的定义,我们应该明白这样一句话:数据即索引,索引即数据
pg索引类型 B-tree、Hash、GiST、SP-GiST 、GIN 和 BRIN
CREATE UNIQUE INDEX name ON table (column [, ...]) using btree;
GiST索引并不是一种单独的索引,而是可以用于实现很多不同索引策略的基础设施。相应地,可以使用一个GiST索引的特定操作符根据索引策略(操作符类)而变化。
和GiST相似,SP-GiST索引为支持多种搜索提供了一种基础结构。
SP-GiST 允许实现众多不同的非平衡的基于磁盘的数据结构,例如四叉树、k-d树和radix树。
GIN 索引是“倒排索引”,它适合于包含多个组成值的数据值,例如数组。倒排索引中为每一个组成值都包含一个单独的项,它可以高效地处理测试指定组成值是否存在的查询。
BRIN表示块范围索引。 BRIN是为处理这样的表而设计的:表的规模非常大,并且其中某些列与它们在表中的物理位置存在某种自然关联。