索引的优缺点
优点 :创建索引可以大大提高系统的性能。
1️⃣可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
2️⃣通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
3️⃣可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
4️⃣在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
缺点:
1️⃣创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
2️⃣索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
3️⃣当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。
索引的种类
常见的索引有hash索引和b+树索引。
对于查询单挑记录较多的情况,hash索引的性能更优。
其他情况一般使用b+树索引。
Mysql为什么使用B+树做索引结构
mysql为什么选取B+树,本质上是因为mysql数据是存放在磁盘存储的。
B+树是为磁盘或其他直接存取的辅助存储设备而设计的一种数据结构。
(1)只有叶子节点才记录数据,非叶子节点只包含索引(叶子节点的最小值),这样,一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了。
(2)能够提供稳定高效的范围扫描(range-query)功能;这也是为什么数据库和操作系统中的文件系统通常会采用b+树作为数据索引的原因,这个特点主要因为所有叶子节点相互连接,并且叶子节点本身依关键字的大小自小而大顺序链接。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。
B树与B+树
B树是为了提高磁盘或外部存储设备查找效率而产生的一种多路平衡查找树。
一棵最小度为t的B树是满足如下四个条件:
(1)每个节点最多包含2t−1个关键字。
(2)一个节点u中的关键字按非降序排列。
(3)每个节点的关键字对其子树的范围分割。
(4)所有叶子节点具有相同的深度,即树的高度h。
B+树为B树的变形结构,用于大多数数据库或文件系统的存储。
以m阶B+树为例:
(1)除根节点外的内部节点,每个节点最多有m个关键字,最少有⌈m/2⌉个关键字。
(2)根节点要么没有子树,要么至少有2棵子树;
(3)所有的叶子节点包含了全部的关键字以及这些关键字指向文件的指针。
B+树中只有叶子节点会带有全部的关键字信息,内部节点仅仅起到索引的作用。而B树则所有节点都带有要查找的有效信息,在内部节点出现的索引项不会再出现在叶子节点中。
B+树中所有叶子节点都是通过指针连接在一起,方便顺序遍历,而B树不会。
聚簇索引、非聚簇索引与联合索引
聚簇索引(Innodb使用)
表中数据按照索引的顺序来存储的,也就是说索引项的顺序与表中记录的物理顺序一致。对于聚集索引,叶子结点即存储了真实的数据行的地址(直达),不再有另外单独的数据页。 在一张表上最多只能创建一个聚集索引,因为真实数据的物理顺序只能有一种。
Innodb中的每张表都会有一个聚集索引,如果一个主键被定义了,那么这个主键就是聚集索引;如果没有主键被定义,那么该表的第一个唯一非空索引被作为聚集索引;如果没有主键也没有合适的唯一索引,那么 innodb 内部会生成一个隐藏的主键作为聚集索引,这个隐藏的主键是一个6个字节的列,该列的值会随着数据的插入自增。
非聚簇索引(Myisam使用)
表中数据存储顺序与索引顺序无关。对于非聚集索引,叶结点包含索引字段值及指向数据页数据行的逻辑指针(不能直达),其行数量与数据表行数据量一致。一个表可以有多个非聚簇索引。
联合索引
联合索引又叫复合索引,两个或更多个列上的索引被称作复合索引,对于复合索引: Mysql 从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分(最左前缀)。
例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找 。当最左侧字段是常量引用时,索引就十分有效。
哪些列适合建立索引?
(1)表的主键、外键必须有索引;
(2)经常与其他表进行连接的表,在连接字段上应该建立索引;
(3)经常出现在Where子句中的字段,特别是大表的字段,应该建立索引;
(4)索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引;
(5)频繁进行数据操作的表,不要建立太多的索引;
(6)列中含有null值,则不要建立索引。
索引是越多越好吗?
索引固然可以提高相应的 select 效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。