MySQL索引基础详细介绍
一 介绍
索引是帮助 MySQL 高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查询算法,这种数据结构就是索引。
二 优缺点
优点:
- 提高数据检索效率,降低数据库的IO成本
- 通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗
缺点:
- 索引列也是要占用空间的
- 索引大大提高了查询效率,但降低了更新的速度,比如 INSERT、UPDATE、DELETE
三 数据结构
索引结构 | 描述 |
---|---|
B+Tree | 最常见的索引类型,大部分引擎都支持B+树索引 |
Hash | 底层数据结构是用哈希表实现,只有精确匹配索引列的查询才有效,不支持范围查询 |
R-Tree(空间索引) | 空间索引是 MyISAM 引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少 |
Full-Text(全文索引) | 是一种通过建立倒排索引,快速匹配文档的方式,类似于 Lucene, Solr, ES |
索引 | InnoDB | MyISAM | Memory |
---|---|---|---|
B+Tree索引 | 支持 | 支持 | 支持 |
Hash索引 | 不支持 | 不支持 | 支持 |
R-Tree索引 | 不支持 | 支持 | 不支持 |
Full-text | 5.6版本后支持 | 支持 | 不支持 |
四 索引分类
- 单列索引,即一个索引只包含单个列,一个表可以有多个单列索引。
- 组合索引,即一个索引包含多个列。
分类 | 含义 | 特点 | 关键字 |
---|---|---|---|
主键索引 | 针对于表中主键创建的索引 | 默认自动创建,只能有一个 | PRIMARY |
唯一索引 | 避免同一个表中某数据列中的值重复 | 可以有多个 | UNIQUE |
常规索引 | 快速定位特定数据 | 可以有多个 | |
全文索引 | 全文索引查找的是文本中的关键词,而不是比较索引中的值 | 可以有多个 | FULLTEXT |
在 InnoDB 存储引擎中,根据索引的存储形式,又可以分为以下两种:
分类 | 含义 | 特点 |
---|---|---|
聚集索引(Clustered Index) | 将数据存储与索引放一块,索引结构的叶子节点保存了行数据 | 必须有,而且只有一个 |
二级索引(Secondary Index) | 将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键 | 可以存在多个 |
五 索引的使用
1.索引查询
//展示表中相关的所有信息
show index from table_name;
执行上述命令后,将会显示指定表中所有索引的详细信息:
包括索引名称(Key_name)、索引列(Column_name)、是否是唯一索引(Non_unique)、排序方式(Collation)、索引的基数(Cardinality)等。
2.索引的创建与删除
//在创建表中定义
//在创建表中定义唯一索引,主键索引,单值索引,复合索引
create table stu( id int AUTO_INCREMENT,
name varchar(20),
age int,
gender varchar(1),
primary key(id), //主键索引
unique index `ind_name` (name) //或者unique 索引名(字段名) 唯一索引
key 索引名(字段名), //单值索引
key 索引名(字段名1,字段名2) //复合索引 );
5.2.1主键索引
- 表中的列设定为主键后,数据库会自动建立主键索引,索引列中的值必须是唯一的,不允许有空值
- 单独创建和删除主键索引的语法
- 创建:alter table 表名 add primary key(字段)
- 删除:alter table 表名 drop primary key
5.2.2唯一索引
- 表中的列创建了唯一约束时,数据库会自动建立唯一索引,索引列中的值必须是唯一的,但是允许为空值。
- 单独创建和删除唯一索引的语法:
- 创建:alter table 表名 add unique 索引名(字段)或create unique index 索引名 on 表名(字段)
- 删除:drop index 索引名 on 表名
5.2.3单值索引(单列索引)
一个索引只包含单个列,一个表可以有多个单值索引。
1.建表时可随表一起建立单值索引
2.单独创建和删除单值索引
- 创建:alter table 表名 add index 索引名(字段)或 create index 索引名 on 表名(字段)
- 删除:drop index 索引名 on 表名
5.2.4复合索引(组合索引)
一个索引包含多个列
1.建表时可随表一起建立复合索引
2.单独创建和删除复合索引
- 创建:create index 索引名 on 表名(字段1,字段2)或 alter table 表名 add index 索引名(字段1,字段2)
- 删除:drop index 索引名 on 表名
5.2.5普通索引
最基本的索引类型,没有唯一性的限制,主要用于提高查询性能。一个表可以有多个普通索引。
CREATE INDEX index_name ON table_name
(column1 [ASC|DESC],column2 [ASC|DESC], ...);
//(column1, column2, ...): 指定要索引的表列名。你可以指定一个或多个列作为索引的组合。这些列的数据类型通常是数值、文本或日期。CREATE TABLE table_name
(column1 data_type,
column2 data_type, ...,
INDEX index_name (column1 [ASC|DESC], column2 [ASC|DESC], ...) ); //创建表的时候直接指定索引
5.2.6全文索引
专门用于全文搜索的索引。只有在MyISAM和InnoDB(从MySQL 5.6版本开始支持)存储引擎的CHAR、VARCHAR或TEXT类型列上才能创建全文索引。
CREATE FULLTEXT INDEX 索引名 ON 表名 (字段名);
5.2.7空间索引
用于空间数据类型的索引,如MySQL的地理数据类型GEOMETRY。这种索引类型主要用于空间数据查询,只有MyISAM存储引擎支持空间索引。
CREATE SPATIAL INDEX sp_idx_location ON parks (location);
//parks表的location列是一个地理数据类型,创建了一个空间索引,用于地理位置查询。
5.2.8前缀索引
对于文本类的长字段,可以创建前缀索引来提高索引效率,只索引字段的前面一部分字符。
create index 索引名 on 表名(字段名(前面几个字符))
如:create index inx_name on student(name(20)) 创建了一个前缀索引,只索引名字的前20个字符。
删除索引
方式一: DROP INDEX index_name ON table_name;
方式二: ALTER TABLE table_name DROP INDEX index_name;
3.索引的使用
索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。
六 使用规则
最左前缀法则
如果索引关联了多列(联合索引),要遵守最左前缀法则,最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列。
如果跳跃某一列,索引将部分失效(后面的字段索引失效)。
联合索引中,出现范围查询(<, >),范围查询右侧的列索引失效。可以用>=或者<=来规避索引失效问题。
索引失效情况
- 在索引列上进行运算操作,索引将失效。如:
explain select * from tb_user where substring(phone, 10, 2) = '15';
- 字符串类型字段使用时,不加引号,索引将失效。如:
explain select * from tb_user where phone = 17799990015;
,此处phone的值没有加引号 - 模糊查询中,如果仅仅是尾部模糊匹配,索引不会是失效;如果是头部模糊匹配,索引失效。如:
explain select * from tb_user where profession like '%工程';
,前后都有 % 也会失效。 - 用 or 分割开的条件,如果 or 其中一个条件的列没有索引,那么涉及的索引都不会被用到。
- 如果 MySQL 评估使用索引比全表更慢,则不使用索引。