Mysql索引
索引是对数据库表中一列或多列的值进行排序的一种结构
索引的简历能大大提高MYSQL运行效率,索引可以大大提高MySQL的检索速度
如果数据库存在大数据量的表,就需要花时间建立最优秀的索引或优化查询语句
MYSQL常用索引结构
B树
多路搜索树,树高一层意味着多一次的磁盘I/O
特点
- 关键字集合分布在整棵树中
- 任何一个关键字只能出现在一个结点中
- 搜索有可能在非叶子结点结束
- 搜索性能等价于在关键字全集内做一次二分查找
B+树
B+树是B树的变体,也是一种多路搜索树
特点
- 所有关键字都出现在叶子结点链表中,且链表中关键字是有序的
- 不可能在非叶子结点命中
- 非叶子结点相当于是叶子结点的索引,叶子结点相当于是存储(关键字)数据的数据层
- 每个叶子结点都包含指向下一个叶子结点的指针,方便从叶子结点的范围遍历
哈希索引
哈希索引采用了一定哈希算法,将键值计算为新的哈希值,通过哈希值直接定位到相应位置,速度非常快。
但是哈希索引经过哈希运算后不保证大小关系,因此无法使用范围过滤
索引存储在文件系统中,同时索引也占据物理空间
索引分类
逻辑分类
按功能划分
- 主键索引:一张表只能有一个主键索引,不允许重复,不允许为NULL
ALTER TABLE TableName ADD PRIMARY KEY(column_list);
- 唯一索引:数据列不允许重复,但是允许为NULL,一张表可以有多个唯一索引,但是列值必须唯一,允许有空。如果是组合索引,则列值组合必须唯一
CREATE UNIQUE INDEX IndexName ON `TableName`(`字段名`(length));
# 或者
ALTER TABLE TableName ADD UNIQUE (column_list);
- 普通索引:一张表可以有多个普通索引,一个普通索引可包含多个字段,允许数据重复,NULL值插入
CREATE INDEX IndexName ON `TableName`(`字段名`(length));
# 或者
ALTER TABLE TableName ADD INDEX IndexName(`字段名`(length));
按列划分
- 单例索引:一个索引只包含一个列,一个表可以有多个单例索引。
- 组合索引:一个组合索引包含两个或两个以上的列。查询的时候遵循 mysql 组合索引的 “最左前缀”原则,即使用 where 时条件要按照建立索引的时候字段的排列方式放置索引才会生效。
物理分类
分为聚簇索引和非聚簇索引(有时也称辅助索引或二级索引)
聚簇索引(B+树)
聚簇索引是一种数据存储方式。这种存储方式是依靠B+树来实现的。
聚簇索引可理解为将数据和主键放在了叶子结点,找到了索引也找到了数据。
每张表最多只能拥有一个聚簇索引。
非聚簇索引
数据和索引是分开的,B+树叶子节点存放的不是数据表的行记录。
索引优化
- InnoDB中主键不宜定义太大,因为辅助索引也会包含主键列,如果主键定义的比较大,其他索引也将很大。如果想在表上定义 、很多索引,则争取尽量把主键定义得小一些。InnoDB 不会压缩索引。
- InnoDB中尽量不使用非单调字段作主键(不使用多列),因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。
应该创建索引的列
- 在经常需要搜索的列上,可以加快搜索的速度
- 在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构
- 在经常用在连接(JOIN)的列上,这些列主要是一外键,可以加快连接的速度
- 在经常需要根据范围(<,<=,=,>,>=,BETWEEN,IN)进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的
- 在经常需要排序(order by)的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
- 在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。
不应该创建索引的列
- 对于那些在查询中很少使用或者参考的列不应该创建索引。
若列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。 - 对于那些只有很少数据值或者重复值多的列也不应该增加索引。
这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。 - 对于那些定义为text, image和bit数据类型的列不应该增加索引。
这些列的数据量要么相当大,要么取值很少。 - 当该列修改性能要求远远高于检索性能时,不应该创建索引。(修改性能和检索性能是互相矛盾的)
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 1300452403@qq.com