数据库-索引

随记-数据库索引

前言

  在学习数据库三级的过程中,对索引的内容进行了简单的概括和介绍,从多方面进行解析。


一、索引概述

索引(index)是帮助MySQL高效获取数据数据结构(有序)。在数据之外,数据库系统还维护者满足特定查找算法的数据结构。这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引

索引(数据结构):红黑树、二叉树、B-Tree、B+Tree

索引概述:

例如语句(select * from user where age = 45)

id

name

age

1

Zhangsan

55

2

lisi

22

3

wangwu

11

4

lierma

42

5

zhangfei

56

6

libai

45

7

huangzhong

89

在无索引的条件下,会进行全表的扫描,数据会一行行的扫描性能低

id

name

age

1

Zhangsan

36

2

lisi

22

3

wangwu

33

4

lierma

48

5

zhangfei

53

6

libai

29

7

huangzhong

45

8

Machao

17

9

Anqila

23

10

wuzetian

20

有索引:


如果像存在这样的二叉树,可以大大减少检索的效率

二、索引的优缺点:

优势

劣势

提高数据检索效率,降低数据库的IO成本

索引列需要占用空间

通过索引列对数据进行排列,降低数据排列成本,降低CPU的消耗

索引大大的提高了查询的效率,同时也降低更新表的速度,如对表进行INSERT、UPDATE、DELETE时,效率降低

三、索引结构的实现

MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的结构

索引结构

描述

R+Tree索引

最常见的索引类型,大部分的引擎都支持B+树索引

Hash索引

底层数据结构是使用哈希表实现的,只有精确匹配索引列的查询才有效,不支持范围查询

R-tree(空间索引)

空间索引是MyISAM引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少

Full-text(全文索引)

通过建立倒排索引(了解过es的都知道),快速匹配文档的方式,类似于Lucene,Solr,ES

索引结构:

索引

InnoDB

MyISAM

Memory

B+tree索引

支持

支持

支持

Hash索引

不支持

不支持

支持

R-tree索引

不支持

支持

不支持

Full-text索引

5.6版本后支持

支持

不支持

平常我们说的索引,没有特别的指明,都是指B+树组织结构的索引

四、索引结构——二叉树

  1. 二叉树索引相对于无索引的全表扫描显然能够大大提高查询的效率,但是也存在缺点:顺序插入时,会形成一个链表,查询性能大大降低。大数据量情况下,层级较深检索速度慢。
  2. 为了解决二叉树的顺序加入问题产生了红黑二叉树,虽说解决了顺序插入形成链表的问题,但是还是存在:大数据量的情况下,层级较深,检索速度慢。
  3. B-Tree(多路平衡查找树)的出现解决了二叉树的顺序平衡问题,一颗最大度数(max-degree)为5(5阶)的b-tree为例(每个节点最多存储4个key,5个指针)

如图:20,30,62,89为key,存在五个指针指向第二层的五个节点

注意:树的度数是指一个节点子节点的个数

五、索引结构——B+Tree

在B树之后人们不断的完善索引结构,产生了B+Tree

最大度数(max-degree)为4(4阶)的B+tree

MySQL索引数据结构对经典的B+Tree进行了优化,增加了一个指针指向相邻叶子节点的链表指针,形成了带有顺序指针的B+Tree,提高区间访问的能力

经典

MySQL优化

注意:B+Tree与B-Tree的区别

  1. B+Tree所有数据都只会出现在叶子节点
  2. 叶子节点形成一个单项的列表

六、索引结构——Hash索引

Hash索引采用一定的hash算法,将键值换算成新的hash值映射到对应的槽位上 ,然后存储在hash表中,如果两个(或者多个)键值,映射到一个相同的槽位上,就会产生hash冲突(也叫hash碰撞),可以通过链表来解决

特点:

  1. Hash索引只能用于对等比较(=,in),不支持范围查询(between,>,<....)
  2. 无法利用索引完成排序操作
  3. 查询效率高,通常只需要一次检索即可,效率通常高于B+Tree

存储索引支持

在MySQL中,支持hash索引的是Memory引擎,而InnoDB具有自适应的hash功能,hash索引是存储引擎根据B+Tree索引在指定条件下自动构建的。

为什么InooDB存储引擎选择使用B+tree索引结构?

  1. 相对于二叉树,层级更少,搜索效率更高
  2. B-tree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针跟着减少,要同样保存大量数据,只能增加树的高度,导致性能降低;
  3. 与Hash索引相比,B+Tree支持范围匹配及排序操作

七、索引的分类

分类

含义

特点

关键字

主键索引

针对于表中主键创建的索引

默认自动创建,只有一个

PRIMARY

唯一索引

避免同一个表中某数据列中的值重复

可以有多个

UNIQUE

常规索引

快速定位特定数据

可以有多个

全文索引

全文索引查找的是文本中的关键词,而不是比较索引中的值

可以有多个

FULLTEXT

在InooDB存储引擎中,根据索引的存储形式,可以分为

分类

含义

特点

聚集引擎(Clustered Index)

将数据存储与索引放到一块,索引结构的叶子节点保存了行数据

必需有,且只有一个

二级索引(Secondary Index)

将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键

可以存在多个

八、聚集索引的选取规则:

  1. 如果存在主键,主键索引就是聚集索引
  2. 如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引
  3. 如果没有主键,或者没有合适的唯一索引,则InooDB会自动生成一个rowid作为隐藏的聚集索引。


索引语法

创建索引:CREATE [UNIQUE|FULLTEXT] INDEX index_name ON table_name (index_col_name....)

查看索引:SHOW INDEX FROM table_name

删除索引: DROP INDEX index_name ON table_name

  1. create index index_name on tb_user(name);
  2. Create unique index index_phone on tb_user(phone);
  3. Create index index_pas on tb_user(profession,age,status);
  4. Create index index_email on tb_user(email);

九、索引的使用:

1.盖索引覆

尽量使用覆盖索引(查询使用了索引,并且需要返回的列,在该索引中全部能够找到),减少select *的使用

在查看索引中(using index condition是查找使用到了索引,但是需要回表查询数据,using where;using index 查找使用了索引,但是需要的数据在索引列中都能够找到,所以不需要回表查询数据)

例如存在如下表:

表中会存在聚集索引,我们再根据表中的name建立一个辅助索引(二级索引)

当我们执行语句:select id,name from tb_user where name = ‘Am’;

可以发现他会访问辅助索引,在辅助索引中他可以找到他想要的id,name不需要进行回表查询,这个被叫做覆盖索引,就是在辅助索引(二级索引)中找到自己想要的所有数据这个就叫做覆盖索引。

一张表,四个字段id,username,password,status数据量大,需要对SQL进行优化,下列语句如何优化

Select id,username.password from tb_user where username = ‘itcast’;

应该是可以考虑建立一个联合索引,这要查找的速率应该是有所提高

Create index index_i_u_p on tb_user(username,password);

2.前缀索引

当字段类型为字符串(varchar,text),需要索引很长的字符串,索引会变得很大,查询时浪费大量的磁盘IO,影响查询效率,此时可以只将字符串中的一部分前缀,建立索引,这样可以大大节省索引空间,从而提高索引效率

语法:

Create index idx_xxx on table_name(column(n));

前缀长度:

可以根据索引的选择性来决定,而选择性是指不重复的索引值(基数)和数据表的记录总数的比值,索引选择性越高则查询效率越高,唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的

Select count(distinct email)/count(*) from tb_user;

Select count(distinct substring(email,1,5))/count(*) from tb_user;


从上图需要注意的是:当我们创建了前缀索引的时候,他会创建如上的索引结构,我们进行如下的SQL语句 : select * from tb_user where email = ‘lvbu666@163.com’,他会查找如上图的辅助索引然后进行回表查询

3.单列索引与联合索引

单列索引:即一个索引值包含单个列

联合索引:即一个索引包含了多个列

在开发中如果存在多个查询条件,考虑针对查询字段建立索引的时候,建议建立联合索引,而非单列索引

注意:多条件联合查询的时候MySQL优化器会评估哪个字段的索引效率更高,会选择该索引完成本次查询

十、索引设计原则:

  1. 针对数据量较大,查询比较频繁的表建立索引
  2. 针对常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引
  3. 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高
  4. 如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引
  5. 尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率
  6. 要控制索引的数量,索引并不是多多益善,索引越多,维护索引的代价越大,会影响增删改的效率
  7. 如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束,当优化器知道每列是否包含NULL值时,他可以更好地确定哪个索引最有效的用于查询

索引是一种数据结构,它可以帮助加快数据库表中数据的检索速度。在 MySQL 数据库中,索引通常被称为 B-tree 索引,它可以加速 SELECT、UPDATE 和 DELETE 操作的速度。在本文中,我们将介绍 MySQL 中的索引,包括索引的类型、如何创建索引、如何使用索引以及索引的优化。 ## 索引的类型 MySQL 支持多种类型的索引,包括以下几种常见的类型: - PRIMARY KEY 索引:用于唯一标识数据库表中的每一行记录。 - UNIQUE 索引:用于确保表中某一列的值是唯一的。 - INDEX 索引:用于加速表中的数据检索操作。 - FULLTEXT 索引:用于全文搜索操作。 ## 如何创建索引MySQL 中,可以使用 CREATE INDEX 语句来创建索引。例如,下面的语句创建一个名为 idx_last_name 的索引,用于加速对 employees 表中 last_name 列的检索: ``` CREATE INDEX idx_last_name ON employees (last_name); ``` 需要注意的是,创建索引可能会增加数据库表的插入、更新和删除操作的时间开销。因此,应该谨慎地考虑是否需要创建索引,以及应该创建哪些索引。 ## 如何使用索引MySQL 中,可以使用 EXPLAIN 语句来查看查询语句的执行计划。如果查询语句使用了索引,则在执行计划中会显示使用的索引名称。例如,下面的语句使用 EXPLAIN 来查看对 employees 表进行 last_name 列检索的执行计划: ``` EXPLAIN SELECT * FROM employees WHERE last_name = 'Smith'; ``` 如果查询语句没有使用索引,则可以使用 FORCE INDEX 语句来强制使用指定的索引。例如,下面的语句强制使用 idx_last_name 索引来对 employees 表进行 last_name 列检索: ``` SELECT * FROM employees FORCE INDEX (idx_last_name) WHERE last_name = 'Smith'; ``` 需要注意的是,强制使用索引可能会导致性能下降。因此,应该仅在必要时使用强制索引。 ## 索引的优化 在 MySQL 中,可以使用 OPTIMIZE TABLE 语句来优化数据库表。优化表可以帮助减少表中的碎片,提高表的查询性能。例如,下面的语句优化 employees 表: ``` OPTIMIZE TABLE employees; ``` 此外,还可以使用 ANALYZE TABLE 语句来分析表中的数据分布情况,以便优化索引。例如,下面的语句分析 employees 表的数据分布情况: ``` ANALYZE TABLE employees; ``` 需要注意的是,索引的性能可能会受到数据分布的影响。如果表中的数据分布不均匀,则可能需要重新设计索引或优化查询语句以提高性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

载着梦想的猪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值