Skip to content

索引

在数据日益增多,数据库会变得越来越臃肿,查询的成本也逐步提高,为了降低查询成本,出现了索引 索引是一种用于查询的有序的数据结构

优点: 可以高效的查询数据,降低IO成本 通过索引排序,降低CPU消耗

缺点: 索引需要空间 降低更新效率


索引结构

索引结构描述
B+Tree最常见的索引结构,大部分引擎支持
Hash索引使用哈希表实现,不支持范围查询
R-Tree索引(空间索引)特殊类,通常用在地理类型的数据上,使用较少
Full-Text索引(全文索引)是一种通过建立倒排索引,快速匹配文档的方式

支持情况


索引分类

主键索引:如果创建主键列,就自动创建主键索引 唯一索引:避免值重复,如果字段有唯一约束,就会创建唯一索引 常规索引:特指的,快速定位数据 全文索引:阿巴阿巴

存储形式分类

主要是通过叶子结点存储的数据区的内容分类的 聚集索引的data区存储的是整行的数据,指针区是id, 但是,查找并不会一直通过查找主键来确定一行数据,也不能将每一个字段做成一个聚集索引,会导致行数据被多次存储,浪费空间 所以就出现了二级索引,二级索引的叶子结点是id,指针可以是各行数据,通过二级索引我们可以找到对应的id,就可以再通过聚集索引来查找数据,这就是为什么聚集索引叫做聚集索引

问题出现了:如果一个表没有主键字段,不就不能生成聚集索引了吗?

超级数据库提供了超级方法!!!


索引语法

创建

sql
create [unique | fulltext] index Index_name on Table_name (index_col_name [,...]);

unique:唯一索引,该字段必须有唯一字段标志 fulltext:全文索引 如果二者都没有,就会默认创建一个常规索引 Index_name:索引名称 Table_name:表名称 index_col_name:字段名称,可以关联多个字段,如果没关联,就被称为单列索引,关联了就被称为组合索引,多列索引


查看

sql
show index from Table_name;

可以查看整张表的索引


删除

sql
drop index Index_name on table_name;

删除指定表的指定索引


索引使用原则

最左前缀法则

对于多列索引,查询时想要使用多列索引,查询的字段必须是使用前缀的,如果不使用左侧字段,则不会使用此索引 例如,一个索引构建的字段有name,gender,age三个字段, 如果只查询age字段,就不会使用这个索引,因为缺少前缀 如果查询name,gender字段,name字段会调用索引,gender不会调用索引,因为gender缺少前缀 总结下来:因为数据结构的原因,对于一个多列索引,必须先查询前面的,后面的才能被查询 注意:where中的字段的排序方式不会影响法则的使用


范围查询

使用返回查询的字段,查询右侧的列索引失效。 例如,一个索引构建的字段有name,gender,age三个字段, 如果查询name,gender>30,age字段,那么age将会失效 如果使用>=就不会失效


计算问题

如果字段被计算,则不能使用索引 例如,一个索引构建的字段有name,gender,age三个字段, 如果查询 substring(name,3,1)就不会使用name索引


引号问题

如果字符串不加引号,索引将会失效


模糊查询问题

尾部模糊就不会失效,头部模糊就会失效 和前面的范围查询问题一样,因为没有明确的起点


or问题

如果查询的条件用or链接,如果前后有无索引字段,就不会使用索引 因为如果存在没有索引的字段,就要全表扫描了,既然要扫描了,再用一遍索引反而是浪费时间


数据分布影响

如果MySQL评估全表扫描比索引效率更高,则放弃使用索引 为什么会放弃呢:MySQL优化器决定的,不是很懂


MySQL提示

就是在SQL中加入提示,告诉数据库使用或者不使用某个索引,达到人为优化的目的 插入位置:where之前

提示词

建议使用:use Index (索引名) 禁止使用:ignore Index (索引名) 必须使用:force Index (索引名)


覆盖索引

对于联合索引,我们在查询时,尽量只查询索引内部的字段,这样仅仅查询索引表就可以获取信息, 如果查询到了索引外部的字段,就需要实行回表查询,就多查询ID索引表,降低了性能


前缀索引

为什么需要前缀索引:在一些表中,字段类型为字符串的时候,如果字符串比较长,做成索引的话,查询起来就会浪费磁盘的IO资源 我们可以只对字符串的前部分建立前缀索引,提高查询效率

创建

sql
create [unique | fulltext] index Index_name on Table_name (index_col_name(n) [,...]);

n:字段前缀


单列索引的效率比联合索引效率低

所以我们推荐使用联合索引


索引的设计原则

1:数据量比较大:超过100w,访问频繁的表,我们一般认为要创建索引 2:尝尝针对 查询条件 where,排序 order by,分组 group by 操作建立索引 3:选择区分度高的字段建立索引,尽量建立唯一索引,区分度越高,效率越高 4:字符串字段,如果字符串比较长,建立前缀索引 5:尽量使用联合索引,使用覆盖索引,节省空间,避免回表查询,提高效率 6:控制索引数量,避免冗余索引 7:如果不能存在NULL值,创建表的时候记得标记,更方便优化器进行优化


Contact me: 1943284256@qq.com