天天看点

一文带你入门于MySQL索引

写在面前: 转眼几个月又过去了,最近学业繁忙,面临着实习找工作、最近在恶补基础与面试题。今天给大家讲解MySQL索引,重拾博客。

MySQL索引

    • 一、索引概述
    • 二、索引的优势与劣势对比
    • 三、索引结构
    • 四、索引设计原则
    • 五、MySQL使用索引
      • 5.1、索引分类
      • 5.2、索引语法
    • 六、MySQL的B+Tree

一、索引概述

MySQL

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

简单来说:在众多数据的情况下,就像书本目录一样能高效的定位查出数据。

示意图:

一文带你入门于MySQL索引

索引基于B+树的数据结构,每个节点都对应着每个表的指定数据。

二、索引的优势与劣势对比

优势:

  • 能够类似于书本的目录索引,提高了数据的检索效率,降低数据库的IO成本。
  • 能够通过索引精确对数据进行排序,降低了数据排序的成本,降低CPU的消耗
  • 唯一索引还能保证每一列的数据一致性。

劣势:

  • 索引增加了查询效率,但是也降低了对增删改的速度。MySQL不仅需要保存数据,还需要保存索引文件信息,需要调整和更新变化后的索引信息。
  • 索引也是一张表,保存了主键和索引字段,指向了实体类记录,还需要占用空间。

三、索引结构

索引是在MySQL的存储引擎层中实现的,而不是在服务器层实现的。所以每种存储引擎的索引都不一定完全相同,也不是所有的存储引擎都支持所有的索引类型的。MySQL目前提供了以下4种索引:

  • BTREE 索引

    : 最常见的索引类型,大部分索引都支持 B 树索引。
  • HASH 索引

    :只有Memory引擎支持 , 使用场景简单 。
  • R-tree 索引

    (空间索引):空间索引是MyISAM引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少,不做特别介绍。
  • Full-text (全文索引)

    :全文索引也是MyISAM的一个特殊索引类型,主要用于全文索引,InnoDB从Mysql5.6版本开始支持全文索引。

MyISAM、InnoDB、Memory三种存储引擎对各种索引类型的支持:

索引 InnoDB引擎 MyISAM引擎 Memory引擎
BTREE索引 支持 支持 支持
HASH索引 不支持 不支持 支持
R-TREE索引 不支持 支持 不支持
Full-Text全文索引 5.6版本后支持 支持 不支持

我们所常用的索引一般都是基于B+树。

四、索引设计原则

索引的设计,需要与当前业务结合,需要考虑一些规则,使得索引使用效率更高效。
  • 对查询频次较高,且数据量比较大的表建立索引。
  • 索引字段的选择,最佳候选列应当从where子句的条件中提取,如果where子句中的组合比较多,那么应当挑选最常用、过滤效果最好的列的组合。
  • 使用唯一索引,区分度越高,使用索引的效率越高。
  • 索引可以有效的提升查询数据的效率,但是索引不是越多越好。对于增删改等DML操作比较频繁的表来说,索引过多,会引入相当高的维护代价,降低DML操作的效率,增加相应操作的时间消耗。另外索引过多的话,MySQL将提高选择的代价。
  • 使用短索引,索引创建之后也是使用硬盘来存储的,因此提升索引访问的I/O效率,也可以提升总体的访问效率。
  • 利用最左前缀,N个列组合而成的组合索引,那么相当于是创建了N个索引,如果查询时where子句中使用了组成该索引的前几个字段,那么这条查询SQL可以利用组合索引来提升查询效率。

五、MySQL使用索引

5.1、索引分类

  • 单值索引 :即一个索引只包含单个列,一个表可以有多个单列索引
  • 唯一索引:索引列的值必须唯一,但允许有空值
  • 复合索引 :即一个索引包含多个列

5.2、索引语法

环境搭建:

CREATE TABLE `city` (
`city_id` int(11) NOT NULL AUTO_INCREMENT,
`city_name` varchar(50) NOT NULL,
`country_id` int(11) NOT NULL,
PRIMARY KEY (`city_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `country` (
`country_id` int(11) NOT NULL AUTO_INCREMENT,
`country_name` varchar(100) NOT NULL,
PRIMARY KEY (`country_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into `city` (`city_id`, `city_name`, `country_id`) values(1,'西安',1);
insert into `city` (`city_id`, `city_name`, `country_id`) values(2,'NewYork',2);
insert into `city` (`city_id`, `city_name`, `country_id`) values(3,'北京',1);
insert into `city` (`city_id`, `city_name`, `country_id`) values(4,'上海',1);
insert into `country` (`country_id`, `country_name`) values(1,'China');
insert into `country` (`country_id`, `country_name`) values(2,'America');
insert into `country` (`country_id`, `country_name`) values(3,'Japan');
insert into `country` (`country_id`, `country_name`) values(4,'UK');
           

创建索引:

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
[USING index_type]
ON tbl_name(index_col_name,...)

index_col_name : column_name[(length)][ASC | DESC]
           

示例:为

city

表中创建

city_name

字段索引

结果:

一文带你入门于MySQL索引

查看索引:

示例:

一文带你入门于MySQL索引

删除索引:

示例:

一文带你入门于MySQL索引

alter命令:

1). alter table tb_name add primary key(column_list);
该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL
2). alter table tb_name add unique index_name(column_list);
这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)
3). alter table tb_name add index index_name(column_list);
添加普通索引, 索引值可以出现多次。
4). alter table tb_name add fulltext index_name(column_list);
该语句指定了索引为FULLTEXT, 用于全文索引
           

以上就是一些索引的使用方法。

六、MySQL的B+Tree

B+树介绍: b+树图文详解

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

示意图:

一文带你入门于MySQL索引

链表加入使得左右相邻的数据更为容易查找,增加了查询的速度。