---恢复内容开始---
一.什么是索引?
在MySQL中也叫一种'键',是存储引擎用于快速查找记录的一种数据结构.
b+ 树:一个高度可控的多路搜索树,目的是每次查询数据时,把磁盘的IO次数控制在一个很小的数量级.
而IO的次数取决于输的高度,所以,磁盘块的空间一定的情况下 ,数据项里的数据占的空间越小,数据项越多,树的高度越低,这样是最好的.(大概高度也就3层吧,因为每次IO用时间大概是0.09毫秒左右,这里我用的7200/分的磁盘来说的,这样的话我们就把它每次查询数据的时间大概控制在了0.3秒以下,这个时间用户是感知不到的,这个速度就可以.)
数据项: 简单来说就是每一层分的条件,分的越细越好找
磁盘块:磁盘块的大小也就是一个数据页的大小,是固定的 大约是4096字节
树的高度: 一层IO一次,它决定了查找的时间
所以我们一般能控制的也就是索引字段的大小,也就是数据项里的数据.
二 为什么要有索引?
加速查询速度
mysql的存储引擎的索引是基于 b+树和hash做的
innodb b+树 聚集索引
myisam b+树 非聚集索引
memory hash
b+树做了什么,为什么他的索引会快?
在非叶子节点不存储相关信息,只存放指针:让输得高度降低了,所有数据寻找的时间是一定的
能够直接找到对应的数据
叶子节点的各个数据之间使用双向连接来表示: 能够更好的进行范围排序相关的操作
要想缩短树的高度,我们能做的事情: 就是让每一列的宽度尽量的小
三 聚集索引和非聚集索引;
聚集索引 (有覆盖索引,可以直接从叶子节点拿到数据,也可以没有覆盖索引,叶子节点不能直接难道数据,拿到的只是一个地址,需要通过辅助索引进一步找到该数据)
辅助索引:如果未定义聚集索引,mysql会取一个唯一索引(unique)注意是只含非空列(自己找一个不是空列的)innodb会
把它作为一个聚集索引去查找数据.
如果辅助索引也没有,innodb就会自己产生一个六个字节的id值,是隐藏的,但是他只能通过他自己特定的方式去触发
一张表只能有一个
只在innodb存储引擎中存在
b+树: 在叶子节点直接拿到数据
所有的数据存储的物理地址是根据索引顺序: 排序快
非聚集索引
每张表可以有多个
在myisam ,innodb中都存在
b+ 树 : 叶子节点会存储数据的指针
所有的数据存储的物理地址和索引顺序无关
如果创建多个非聚集索引,那么insert delete 数据都会非常慢,并且占用更多的内存和硬盘
四 mysql所以管理:
1 mysql中的primary key , unique ,联合唯一也都是索引,这些索引除了加速差以外,还有约束功能.
2 唯一索引:
主键索引 :primary key (加速查找+约束,且不为空,不能重复)
唯一索引:unique (加速查找+约束,且不能重复)
3 联合索引:
primary key(id,name) 联合主键索引
unique(id,name) 联合唯一索引
index(id ,name) 联合普通索
五 索引的两大类型hash与btree
#我们可以在创建上述索引的时候,为其指定索引类型,分两类 hash类型的索引:查询单条快,范围查询慢 btree类型的索引:b+树,层数越多,数据量指数级增长(我们就用它,因为innodb默认支持它) #不同的存储引擎支持的索引类型也不一样 InnoDB 支持事务,支持行级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引; MyISAM 不支持事务,支持表级别锁定,支持 B-tree、Full-text 等索引,不支持 Hash 索引; Memory 不支持事务,支持表级别锁定,支持 B-tree、Hash 等索引,不支持 Full-text 索引; NDB 支持事务,支持行级别锁定,支持 Hash 索引,不支持 B-tree、Full-text 等索引; Archive 不支持事务,支持表级别锁定,不支持 B-tree、Hash、Full-text 等索引;
六 创建/删除索引的语法:
#方法一:创建表时 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. 一定是为搜索条件的字段创建索引,比如select * from s1 where id = 333;就需要为id加上索引 #2. 在表中已经有大量数据的情况下,建索引会很慢,且占用硬盘空间,建完后查询速度加快 比如create index idx on s1(id);会扫描表中所有的数据,然后以id为数据项,创建索引结构,存放于硬盘的表中。 建完以后,再查询就会很快了。 #3. 需要注意的是:innodb表的索引会存放于s1.ibd文件中,而myisam表的索引则会有单独的索引文件table1.MYI MySAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在innodb中,表数据文件本身就是按照B+Tree(BTree即Balance True)
组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。
这个索引的key是数据表的主键,因此innodb表数据文件本身就是主索引。 因为inndob的数据文件要按照主键聚集,所以innodb要求表必须要有主键(Myisam可以没有),
如果没有显式定义,则mysql系统会自动选择一个可以唯一标识数据记录的列作为主键
,如果不存在这种列,则mysql会自动为innodb表生成一个隐含字段作为主键,这字段的长度为6个字节,类型为长整型.
七 : 正确使用索引
待续......
---恢复内容结束---