原理
想要了解索引的原理必须弄清楚一种数据结构,(平衡树)也就是B树或者B+树,
我们平时建表的时候都会为表加上索引,在某些关系型数据库中,如果建表不指定主键,数据库不会建表成功,实际上一个加了主键的表,不能称为表。一个没加主键的表,它的数据无序的放置在磁盘存储器中,一行一行的排列很整齐,这才跟表很类似。
如果加上了主键,那么表在磁盘上的存储结构就由整齐的表结构转变成了树状结构,也就是平衡树的结构,整个表变成了一个索引(主键索引),整个表变成一个索引,也就是所谓的聚簇索引,这也就是为什么一个表只能有一个主键了,主键的作用就是将表转换为树结构的格式放置
如果不加索引的话,每次的搜索查询,基本上需要将所有的数据都从磁盘中取出,判断一遍,不过肯定不是全部,肯定有自己的优化查询规则,但是如果加了索引,查询次数就成为了树的高度,大大增加效率
但是索引可以让数据库查询数据的速度上声,而使写入数据的速度下降,原因很简单,因为平衡树整个结构必须一直维持这个状态,数据的删除,增加,修改,都会改变平衡树节点的索引内容,破坏树结构,因此每次数据修改时,DBMS(数据库管理系统)必须去重新梳理树的结构,以保证平衡,这会带来不小的性能开销,
特点
可以加快数据库检索的速度
减低数据库插入,修改,删除等维护的速度
只能创建在表上,不能创建到视图上
既可以直接创建又可以间接创建
可以在优化隐藏中使用索引
使用查询处理器执行sql语句,在一个表上一次只能使用一个索引
优点
创建唯一性索引,保证数据库表中每一行数据的唯一性
大大加快数据的检索速度,这是创建索引的主要原因
加快数据库之间的连接,特别是实现数据的参考完整性方面特别有意义
在使用分组和排序字句进行数据检索时,同样可以显著减少查询中分组和排序的时间
通过使用索引,可以在查询中使用优化隐藏器,提高系统的性能
索引的缺点
创建索引和维护索引需要时间,这种时间随着数据量的增加而增加
索引需要占用物理空间
当对数据中的表数据进行增加,删除,和修改的时候,索引也需要维护,降低数据维护的速度
索引的分类
直接创建索引和间接创建索引
普通索引和唯一性索引
单个索引和复合索引
聚簇索引和非聚簇索引
索引类型
索引方法
聚簇索引(主键索引)
主键索引就是聚簇索引
将主键按照字段当作做索引字段,索引树,叶子节点存放着真实数据,整个表就是一个索引
innodb的主键索引就是聚簇索引(只有主键是,默认的),只有一些引擎才可以支持创建新的聚簇索引
InnoDB 支持事务,支持行级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;
MyISAM 不支持事务,支持表级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引;
Memory 不支持事务,支持表级别锁定,支持 B-tree、Hash 等索引,不支持 Full-text 索引;
NDB 支持事务,支持行级别锁定,支持 Hash 索引,不支持 B-tree、Full-text 等索引;
Archive 不支持事务,支持表级别锁定,不支持 B-tree、Hash、Full-text 等索引;
非聚簇索引
除了聚簇索引,其他的索引都是非聚簇索引,都是用的平衡树的数据结构
索引树的叶子节点存放的不是真实数据,而是数据地址,需要在进行依次查询才能获取到真实数据(称为回表),非聚簇索引查询依次不能获取数据,需要二次查询,
除非是覆盖索引,就是值查询的数据,正好是索引字段,不需要额外查询数据就可以直接返回
普通索引(Normal)
常用的索引(复合索引也是普通索引)
包含一个特殊的,前缀索引:
给一些字符串类型的字段加索引的时候,整个字段都会进入到索引树中,占用空间比较大,索引允许加前缀索引,只取字段的前面一部分作为索引值,减小空间消耗,不过会增加查询扫描的行数(在索引的后面加长度就可以),而且使用了前缀索引,必须要回表(二次查询)因为索引值不全,
altertableUseraddindex index1(email);
altertableUseraddindex index2(email(6));
唯一索引(Unique)
表示唯一的,不允许重复的索引,比如身份证号之类的
约束唯一标识数据表中的每一条数据,在数据表中数据单列时唯一的,Unique(要求列唯一)和Primary Key(primary key = unique + not null 列唯一)(主键)约束均为列或者列集合中提供了唯一性的保障,不过主键只有一个,unique每个表可以有多个
数据重复会报错 : Duplicate entry ‘新加的’ for key ‘name
全文索引(Full Text)
标识全文搜索,在检索长文本的时候,效果最好,短文本建议使用普通索引,
在检索数据量比较大的时候,将数据放入一个没有全局索引的表中,然后创建全文苏哦因,要比先建一张表,建立索引,再写入数据快,
只有MyISAM 支持全文索引(mysql5.6之前),而且检索的字段必须是char,varchar ,text。
需要修改配置信息,词的场地,字符集,等等,都需要配置一下
使用全文索引,sql语句使用MATCH ,还有boolean(有区别,不用全部包含索引的字符,不太清楚)
例子:
SELECT FROM articles WHERE MATCH (tags) AGAINST (‘旅游’ IN BOOLEAN MODE);
索引方式:就是跟在后边的那个 IN 什么的
自然语言检索: IN NATURAL LANGUAGE MODE
布尔检索: IN BOOLEAN MODE
剔除一半匹配行以上都有的词,譬如说,每个行都有this这个字的话,那用this去查时,会找不到任何结果,这在记录条数特别多时很有用,
原因是数据库认为把所有行都找出来是没有意义的,这时,this几乎被当作是stopword(中断词);但是若只有两行记录时,是啥鬼也查不出来的,
因为每个字都出现50%(或以上),要避免这种状况,请用IN BOOLEAN MODE。
查询扩展检索: WITH QUERY EXPANSION
搜索语法规则:
+ 一定要有(不含有该关键词的数据条均被忽略)。
- 不可以有(排除指定关键词,含有该关键词的均被忽略)。
> 提高该条匹配数据的权重值。
< 降低该条匹配数据的权重值。
~ 将其相关性由正转负,表示拥有该字会降低相关性(但不像 - 将之排除),只是排在较后面权重值降低。
万用字,不像其他语法放在前面,这个要接在字符串后面。
“ “ 用双引号将一段句子包起来表示要完全相符,不可拆字。
空间索引(SPATIAL)
空间索引时对空间数据类型的字段建立的索引,mysql中的空间数据有4中:GEOMETRY、POINT、LINESTRING、POLYGON,使用关键字 SPATIAL进行扩展,使得能够用于创建正规索引类型的语法创建空间索引,
创建空间索引的列,必须将其声明为 not null ,空间索引只能用在MYISAM引擎的表中创建
B+树
就不多说了,树结构那已经说了很多,数据库主流都是使用B+树当做数据结构,一般说的B树,也就是B+树,
需要根节点一直查询到叶子节点才能查询到数据
哈希索引(HASH)
性质
因为hash结构的特殊性,检索效率特别高,可以一次定位,高于B+树
仅满足 = in <=>(不等于) 查询 ,不能使用范围查询
缺点
不能用于范围查询
无法利用索引来排序,因为hash计算的值跟原本的值的大小完全不一致,所以数据库无法利用索引的数据来避免任何排序运算
不能利用部分索引键查询,复合索引,使用前面的也不能命中,因为hash是合并后进行的hash计算,不能单独使用
任何形况下都需要表扫描,因为hash 是将索引健同各国hash运算后,将hash计算的值跟对应的数据指针存放在一个hash表中,由于不同的数据健存在相同的hash值,所以即使取满足hash键值的记录条数,也需要扫描全部数据,还要通过访问表的实际数据进行比较,得出相应的结果,
当hash索引遇到大量hash值相等的情况下,不一定比B+树索引快
自适应哈希索引
InnoDB引擎有一个特殊的功能叫做“自适应哈希索引”,由Mysql自动管理,不需要DBA人为干预。默认情况下为开启,我们可以通过参数innodb_adaptive_hash_index来禁用此特性。
当InnoDB注意到某些索引值被使用得非常频繁时,它会在内存中基于缓冲池中的B+ Tree索引上再创建一个哈希索引,这样就上B-Tree索引也具有哈希索引的一些优点,比如快速的哈希查找。
- 只能用于等值比较,例如=, <=>,in ;
- 无法用于排序
InnoDB官方文档显示,启用自适应哈希索引后,读和写性能可以提高2倍,对于辅助索引的连接操作,性能可以提高5倍