数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询,更新数据库中表的数据.
索引的实现通常使用B树和变种的B+树(mysql常用的索引就是B+树)
索引是在存储引擎中实现的,也就是说不同的存储引擎,会使用不同的索引。
MyISAM和InnoDB存储引擎:只支持BTREE索引,也就是说默认使用BTREE,不能够更换。
MEMORY/HEAP存储引擎:支持HASH和BTREE索引
MySQL的索引有普通索引,唯一索引,主键索引、组合索引、全文索引。
为什么要使用联合索引
这里提一下最左前缀原则
联合索引(col1,col2,col3),实际相当于建了(col1),(col1,col2),(col1,col2,col3)三个索引。
比如给a,b,c
加上索引,那么a,b
可以用到索引,a,c
也可以用到索引,但b,c
是用不到的。
包括这个a
必须要在用到的第一个索引处。
本节参考文献:铁柱同学的回答 和这个大佬的回答
# 方法一:创建表时
CREATE TABLE 表名 (
字段名1 数据类型 [完整性约束条件…],
字段名2 数据类型 [完整性约束条件…],
[UNIQUE | FULLTEXT | SPATIAL ] INDEX | KEY
[索引名] (字段名[(长度)] [ASC |DESC])
);
#方法二:CREATE在已存在的表上创建索引
CREATE [UNIQUE | FULLTEXT | SPATIAL ] INDEX 索引名
ON 表名 (字段名[(长度)] [ASC |DESC]) ;
#方法三:ALTER TABLE在已存在的表上创建索引
ALTER TABLE 表名 ADD [UNIQUE | FULLTEXT | SPATIAL ] INDEX
索引名 (字段名[(长度)] [ASC |DESC]) ;
#删除索引:DROP INDEX 索引名 ON 表名字;
******************************举例********************************************************
1.创建索引
-在创建表时就创建(需要注意的几点)
create table s1(
id int ,#可以在这加primary key
#id int index #不可以这样加索引,因为index只是索引,没有约束一说,
#不能像主键,还有唯一约束一样,在定义字段的时候加索引
name char(20),
age int,
email varchar(30)
#primary key(id) #也可以在这加
index(id) #可以这样加
);
-在创建表后在创建
create index name on s1(name); #添加普通索引
create unique age on s1(age);添加唯一索引
alter table s1 add primary key(id); #添加主键索引,也就是给id字段增加一个主键约束
create index name on s1(id,name); #添加普通联合索引
2.删除索引
drop index id on s1;
drop index name on s1; #删除普通索引
drop index age on s1; #删除唯一索引,就和普通索引一样,不用在index前加unique来删,直接就可以删了
alter table s1 drop primary key; #删除主键(因为它添加的时候是按照alter来增加的,那么我们也用alter来删)
本节的参考文献在这里。
hash 的查找时间复杂度是O(1)比B+的O(logn)查找时间更短,为什么索引不用hash?
(可以从B+树索引的有序性,叶节点被双向链表连接,方便支持范围查找,以及分批加载至内存这几个方面回答)
这和业务场景有关,如果只查找一个值的话,hash是一个很好的选择,单数据库经常会选择多条,这时候由于B+树索引有序,并且又有链表相连,它的查询效率比hash就快很多了。而且数据库中的索引一般是在磁盘上,数据量大的情况可能无法一次装入内存,B+树的设计可以允许数据分批加载,同时树的高度较低,提高查找效率
参考文献在这
为什么不用红黑树(可以从内存,以及树深度和IO次数方面讨论这个问题。)
为什么不用B树(可以从叶节点是否存数据,占用内存空间大小和是否支持范围查询这三个方面解释。 )
(比如一个节点是一个页4096字节,其中每条数据128字节,那么一个节点只能存32个数据项,那么对应的孩子节点数最多为33个,这显然不够用。而b+树内部节点只作为导向作用,只存一个整数就可以(int型整数32位,消耗4个字节),4096/4=1024个数据项。这样b+树的每个节点的孩子数更多,整个树的高度就更低,大大增加查询效率。)
B树、B+树和红黑树的参考文献在这。
索引的优点
索引的缺点
主键自动建立唯一索引
在经常用在连接(join)的列上,这些列主要是一些外键,可以加快连接的速度
在经常需要根据范围搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;
频繁作为查询条件(经常where)的字段应该创建索引
查询中经常(OrderBy)排序的字段(因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间)
查询中统计(Count)或者分组(Groupby)的字段;
索引什么时候会失效?
字符串不加单引号(where name=litao这样会失效)
索引列上的任何操作均会失效(计算,函数,类型转换)
尽量使用覆盖索引(避免select*,尽量使查询列和索引列一致)