索引是什么
- 索引是一种帮助数据库高效获取数据的数据结构,它是表中一列或者若干列值的集合和指向表中物理标识这些值的数据页的逻辑指针,比如一本书的目录部分,指向了具体的章节和页号,可以快速的定位数据,提高查询效率。
索引的原理
-
B-树
B-树的特点:
a. 一个m阶的B-树,每个节点最多有m个子节点
b.每个节点除了索引值外还包含行的数据
image.png B+树
- B+树的特点:
a. 非叶子节点只存储索引数据,不存行数据,
b. 指针存储子节点的地址信息
c.叶子节点有序且是一个双向链表结构
为什么非叶子节点只存储所以数据,不存行数据?
a. 增加节点索引值的个数,减少树的深度
b. 减少索引查询时磁盘I/O次数
image.png
- Hash
如下图,hash索引是指通过hash函数计算hash值存储到对应的槽位中,如果有hash冲突可通过链表法或者再hash等方法解决
hash索引特点:
1、可用于 = 或者 in 的查询,不支持范围查询(between,>,<)的查询
2、不可用于排序查询
3、查询效率高,一次查询即可命中结果(没有出现链表的情况下)
image.png
索引有哪些
按存储结构区分
B-树索引
B+树索引
Hash索引
按用途区分
- 普通索引
一般指为了提高查询效率所创建的索引,没有其他的特性。 - 主键索引
每张表都会有自己的主键索引,主键索引不允许为null,当没有显式指定表的主键时,InnoDB会先检查表中是否有唯一索引的字段,如果有,则选择该字段为默认的主键,否则将自动创建一个6字节的自增主键。 - 唯一索引
唯一索引的属性列值不允许重复,但是允许为空。建立唯一索引的目的大部分是为了属性列的数据唯一性,而不是为了查询效率。 - 前缀索引
前缀索引只适合字符串类型的数据,前缀索引是对文本的前几个字符串创建索引,比普通索引建立的索引空间更小,因为只取前几个字符。 - 全文索引
- MySQL中的全文索引是FultLeXT类型的索引。
- 全文索引只能用于InnoDB或MyISAM表,只能为CHAR、VARCHAR、TEXT列创建。
- 在MySQL 5.7.6中,MySQL提供了支持中文、日文和韩文(CJK)的内置全文ngram解析器,以及用于日文的可安装MeCab全文解析器插件
- 当创建表时,可以在CREATE TABLE语句中给出FULLTEXT索引定义,或者稍后使用ALTER TABLE或CREATE INDEX添加该定义。
- 对于大型数据集,将数据加载到没有FULLTEXT索引的表中然后创建索引要比将数据加载到具有现有FULLTEXT索引的表中快得多。
- 空间索引
- 空间索引是一种将空间数据存储在数据库中的索引方式。它可以提高空间数据的查询效率,减少查询时间,同时也可以优化空间数据的存储方式。
- 当需要查询某个区域内的空间数据时,如果没有空间索引,数据库会扫描整个表,查询效率会非常低下。而建立空间索引可以将空间数据分成多个小区域,缩小查询范围,提高查询效率
- 这个空间类型的列必须使用MySQL提供的空间数据类型进行定义,例如POINT、LINESTRING、POLYGON等
- 空间索引的优点是可以提高查询效率,缩小查询范围,同时也可以优化空间数据的存储方式。但是,空间索引的缺点是建立索引需要占用大量的存储空间,同时也会影响更新和插入操作的速度
按查询次数分
- 聚集索引
聚集索引即索引结构和数据一起存放的索引。主键索引属于聚集索引(InnoDB中也只有主键索引才能使聚集索引),聚集索引通过主键查询时可以直接返回数据,不需要经过回表查询 - 辅助索引(非聚集索引)
非聚集索引即索引和数据分开存放的索引,非聚集索引通过索引定位到id(主键),再通过id回表查询行数据。不过也不一定需要回表,如果建立了的是覆盖索引则可以直接返回要查询的数据 - 覆盖索引
如果一个索引包含所有需要查询的字段的值,我们就称之为“覆盖索引”,比如我们下面的sql
select name from t_user,当我们给name建立了索引后,如果是InnoDB存储引擎,会在叶子节点存储name的值以及主键,当我们只需要查询name时,可以直接在叶子节点中获取到,不需要回表
索引的作用
- 索引大大减少了服务器需要扫描的数据量
- 索引可以帮助服务器避免排序和临时表
- 索引可以将随机I/O变为顺序I/O
索引怎么用
- 给哪些字段建索引
1、索引字段主要是根据我们的业务来确定,一般来说如果业务查询条件建立索引会提高查询效率,如果是表数据太多则建议使用第三方搜索引擎比如elasticsearch等查询到主键后在从数据库获取数据 - 索引失效的场景
一般是指sql的where字段没有使用到索引,可以用一句话总结:模型数空运最快
模:模糊查询
型:sql的类型和字段类型不一致
数:对条件字段做函数运算
空:字段为空时,不建立索引,所以不会用到
运:做一些运算操作,比如加减乘除
最:最左匹配原则
快:mysql的优化策略认为不走索引时查询的数据最快会不走索引,可以通过force index强制走索引查询