# 索引
索引(index)是一种快速查询表中内容的机制,类似于字典的目录。它运用在表中的某些字段上,但存储时,独立于表之外。它是用于提高数据库表数据访问速度的数据库对象。
数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、庚戌年数据库表中的数据。
索引的实现通常使用B树及其变种B+树。
- 索引可以避免全盘扫描。多数查询可以仅扫描少量索引页及数据页,而不是遍历所有数据页。
- 对于非聚集索引,有些查询甚至不用访问数据页。
- 对于聚集索引,可以避免数据插入操作集中于表的最后一个数据页。
- 在某些情况下,查询甚至可以不用访问数据页。
分类:
- 唯一索引:唯一索引不允许两行具有相同的索引值
- 主键索引:为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引会要求主键中的每个值都是唯一的,并且不能为空
- 聚集索引(Clustered):表中各行的物理顺序与键值的逻辑(索引)的顺序是相同的,每个表中只能有一个
- 非聚集索引(Non-Clustered):非聚集索引指定了表的逻辑顺序。数据存储在一个位置,索引存储在另一个位置,而索引中包含了指向数据存储位置的指针。数量可以有多个,但是要小于249个
# 特点
- 索引一旦建立,Oracle系统会对其自动维护,而且由Oracle系统决定何时使用索引
- 用户不用在查询语句中指定要使用哪个索引
- 在定义了
primary key
或者unique
约束后,系统会自动在相应的列上创建索引 - 用户可以根据自己需求,对指定的单个字段或者多个字段,添加索引
# 优缺点
# 优点
- 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性
- 可以大大加快数据的检索速度(创建索引的最主要原因)
- 可以加速表和表之间的连接,特别是实现数据的参考完整性方面特别有意义
- 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间
- 通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能
# 缺点
- 创建索引和维护索引需要耗费时间,这种时间随着数据量的增加而增加
- 索引需要占用物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果建立的是聚集索引,那么需要的空间会更大
- 当对表中的数据进行增加、删除和修改的时候,索引也要动态地维护,相当于降低了数据的维护速度
# 语法
# 创建索引
// 普通索引
alter table table_name add index index_name (column_list);
// 唯一索引
alter table table_name add unique (column_list);
// 主键索引
alter table table_name add primary key (column_list);
创建索引的方式包括普通索引、unique
索引和primary key
索引,table_name
是要增加索引的表名,column_list
是指出对哪些列要进行索引,如果是多列时,各列之间用逗号分隔。索引名index_name
是可选的,如果缺醒,MySQL会根据第一个索引列赋一个名称。
create index index_name on table_name (column_list);
create unique index index_name on table_name (column_list);
这同样是一种创建索引的方法,与alter
语句具有相同的含义,索引名是不可选的。除此之外,不能用create index
语句创建primary key
索引。
# 删除索引
drop index index_name on table_name;
alter table table_name drop index index_name;
alter table table_name drop primary key;
在前两句中,是使用不同的命令删除了table_name
中的索引index_name
,而最后一句则是删除primary key
的索引中才会使用。如果没有创建primary key
索引,但是表具有一个或多个unique
索引,就删除第一个unique
索引。
# 场景
需要创建索引的场景:
- 表经常要进行
select
操作 - 表很大(很多记录),记录的内容分布范围也很广
- 列名经常在
where
子句或者连接条件中出现
不需要创建索引的场景:
- 表经常要进行
insert
、update
或delete
操作 - 表很小,记录很少
- 列名不经常在
where
子句或者连接条件中出现
# 创建索引的注意事项
- 非空字段:
- 取值离散大的字段:
- 索引字段越小越好: