一种帮助mysql提高效率的数据结构。
大大加快我们的查询速度。
设定为主键后数据库会自动创建索引 innodb中为聚簇索引 存的值不允许为null
就是我们为其他字段创建的索引 (除了主键字段之外的其他字段)允许为null
创建唯一索引的目的不是为了提高访问速度,而只是为了避免数据出现重复。唯一索引可以有多个但索引列的值必须唯一,索引列的值允许有空值。如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该使用关键字UNIQUE。
复合索引就是将多个字段组合到一块创建索引 eg(age+name)
敲黑板了:复合索引是如何被调用的 需要符合什么原则
对该字段进行全文搜索。
CREATE TABLE USER(
id int PRIMARY key,
age int,
name VARCHAR(20),
KEY(age)
);
show index from user;//显示出我们的索引
CREATE TABLE USER(
id int PRIMARY key,
age int,
name VARCHAR(20)
);
-- 创建一个索引(create)
CREATE index ageIndex on USER(age);
-- 创建一个索引(Add)
ALTER TABLE USER add INDEX(age);
-- 删除一个索引
drop index age on USER;
-- 展示我们创建的索引
show index from user;
上方我们创建的索引都是单值索引。
CREATE TABLE USER(
id int PRIMARY key,
age int,
name VARCHAR(20)
);
-- 创建一个索引(create)
CREATE unique index ageIndex on USER(age);
-- 创建一个索引(Add)
ALTER TABLE USER add Unique index (name);
-- 删除一个索引
drop index age on USER;
-- 展示我们创建的索引
show index from user;
CREATE TABLE USER(
id int PRIMARY key,
age int,
name VARCHAR(20)
);
-- 创建一个索引(create)
CREATE index ageAndNameIndex on USER(age,name);
-- 删除一个索引
drop index ageIndex on USER;
-- 展示我们创建的索引
show index from user;
我们插入无须的数据 根据id无序插入
---建表
create table t_emp(id int primary key,name varchar(20),age int);
--插入数据
insert into t_emp values(5,'d',22);
insert into t_emp values(6,'d',22);
insert into t_emp values(7,'e',21);
insert into t_emp values(1,'a',23);
insert into t_emp values(2,'b',26);
insert into t_emp values(3,'c',27);
insert into t_emp values(4,'a',32);
insert into t_emp values(8,'f',53);
insert into t_emp values(9,'v',13);
--查询
select * from t_emp;
参考:B+树
B+Tree是在B-Tree(B树的)基础上的一种优化,使其更适合实现外存储索引结构,InnoDB存储引擎就是用B+Tree实现其索引结构。
B-Tree结构图中可以看到每个节点中不仅包含数据的key值,还有data值。而每一个页的存储空间是有限的,如果data数据较大时将会导致每个节点(即一个页)能存储的key的数量很小,当存储的数据量很大时同样会导致B-Tree的深度较大,增大查询时的磁盘I/O次数,进而影响查询效率。
在B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样可以大大加大每个节点存储的key值数量,降低B+Tree的高度。
B+Tree相对于B-Tree有几点不同:
实际情况中每个节点可能不能填充满,因此在数据库中,B+Tree的高度一般都在2-4层 mysql的InnoDB存储引擎在设计时是将根节点常驻内存的,也就是说查找某一键值的行记录时最多只需要1~3次磁盘I/O操作。(注意顶层页一般在内存 不需要进行I/O操作)
InnoDB使用的是聚簇索引,将主键组织到一棵B+树中,而行数据就储存在叶子节点上,若使用"where id = 14"这样的条件查找主键,则按照B+树的检索算法即可查找到对应的叶节点,之后获得行数据。
若对Name列进行条件搜索,则需要两个步骤:第一步在辅助索引B+树中检索Name,到达其叶子节点获取对应的主键。第二步使用主键在主索引B+树种再执行一次B+树检索操作,最终到达叶子节点即可获取整行数据。(重点在于通过其他键需要建立辅助索引)
聚簇索引默认是主键,如果表中没有定义主键,InnoDB 会选择一个唯一且非空的索引代替。如果没有这样的索引,InnoDB 会隐式定义 一个主键(类似oracle中的RowId)来作为聚簇索引。如果已经设置了主键为聚簇索引又希望再单独设置聚簇索引,必须先删除主键,然后添加我们想要的聚簇索引,最后恢复设置主键即可。
在辅助索引的叶子节点找到主键值 再到主键索引寻找行数据的操作称为回表
MyISAM使用的是非聚簇索引,非聚簇索引的两棵B+树看上去没什么不同,节点的结构完全一致只是存储的内容不同而已,主键索引B+树的节点存储了主键,辅助键索引B+树存储了辅助键。表数据存储在独立的地方,这两颗B+树的叶子节点都使用一个地址指向真正的表数据,对于表数据来说,这两个键没有任何差别。由于索引树是独立的,通过辅助键检索无需访问主键的索引树。
每次使用辅助索引检索都要经过两次B+树查找(Innodb中辅助索引是建立在聚簇索引之上的),看上去聚簇索引的效率明显要低于非聚簇索引,这不是多此一举吗?聚簇索引的优势在哪?
由于行数据和聚簇索引的叶子节点存储在一起,同一页中会有多条行数据,访问同一数据页不同行记录时,已经把页加载到了Buffer中(缓存器),再次访问时,会在内存中完成访问,不必访问磁盘。这样主键和行数据是一起被载入内存的,找到叶子节点就可以立刻将行数据返回了,如果按照主键Id来组织数据,获得数据更快。
辅助索引的叶子节点,存储主键值,而不是数据的存放地址。当发生增删改的时候 在innodb中我们只需要维护主键索引即可 辅助索引不用维护 因为主键值唯一 我们只需要维护一部分即可,但在myisam中我们需要修改两部分不仅要在存数据的部分进行修改 而且也需要修改辅助索引的叶节点(因为地址可能变化)。另一个好处是,因为辅助索引存放的是主键值,减少了辅助索引占用的存储空间大小。
聚簇索引的数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的。如果主键不是自增id,那么可以想象,它会干些什么,不断地调整数据的物理地址、分页,当然也有其他一些措施来减少这些操作,但却无法彻底避免。但,如果是自增的,那就简单了,它只需要一页一页地写,索引结构相对紧凑,磁盘碎片少,效率也高。
<1. 查询语句中使用LIKE关键字
在查询语句中使用 LIKE 关键字进行查询时,如果匹配字符串的第一个字符为“%”,索引不会被使用。如果“%”不是在第一个位置,索引就会被使用。
<2.查询语句中使用多列索引
多列索引是在表的多个字段上创建一个索引,只有查询条件中使用了这些字段中的第一个字段,索引才会被使用。最左匹配原则 即多个字段组成的复合索引 如果想要被调用 那么查询条件中必须包含建立索引的第一个字段
❤️.查询语句中使用OR关键字
查询语句只有OR关键字时,如果OR前后的两个条件的列都是索引,那么查询中将使用索引。如果OR前后有一个条件的列不是索引,那么查询中将不使用索引。
age name grade (其中age 跟name建立了索引 grade未建立索引)
where age and name (调用了索引)
where age or name (也调用了索引)
where grade or age(未调用索引)