2.mysql索引
一、MySQL的数据结构类型
1、B树
数据在各个节点上
三层即 百万数据
2、B+树
数据在叶子节点上
3、为什么使用B/B+树
红黑树等数据结构也可以实现索引,但是文件系统以及数据库系统普遍使用B+树来作为索引结构。
Mysql是基于 磁盘 的数据库系统,索引往往以 索引的形式 存储于磁盘上,索引查找过程中就要产生磁盘消耗。
相对于内存读取,I/O存储的消耗要高 上 几个数量级 ,索引的结构组织 要减少 读取磁盘的次数。为什么使用B+树,还是与磁盘存取原理有关
4、为什么使用B+树?
1、B+树更适合外部存储,由于节点无data域,一个节点可以存储更多个内节点,每个节点的范围更大更精确,也意味着B+树单次磁盘IO的信息量高于B树。即没有数据可以存储更多的id
2、Mysgl是一种关系型数据库,区间访问是常见的一种情况,B+树叶节点增加的链指针;加强了区间访问性,可使用在范围区间查询等,而B-树每个节点 key和data在一起,则无法区间查找。
5、索引怎么查询
- 从索引里自上而下的查询
- 走到叶子节点查询到id
- 根据id去聚簇索引中找到真正的数据,这个过程叫做回表,其他普通的索引查找过程
- 如果你要找的数据索引都有了不需要回表,就叫索引覆盖
6、索引的分类和创建
6.1、聚簇索引和非聚簇索引
6.1.1、聚簇索引:索引和数据放在一起叫聚簇索引(一次遍历找到数据,不需要回表)
6.1.2、非聚簇索引:索引和数据不在一起(需要会回表再查一次找到真正的数据)
红线:非聚簇索引
绿线:聚簇索引
1、 InnoDB使用的是聚簇索引,将主键组织到一棵B+树中,而行数据就储存在叶子节点上,若使用"where id =14"这样的条件查找主键,则按照B+树的检索算法即可查找到对应的叶节点,之后获得行数据。
2、若对Name列进行条件搜索,则需要两个步骤:第一步在辅助索引B+树中检索Name,到达其叶子节点获取对应的主键。第二步使用主键在主索引B+树种再执行一次B+树检索操作,最终到达叶子节点即可获取整行数据。(重点在于通过其他键需要建立辅助索引)
聚簇索引具有唯一性,由于数据和聚簇索引放在一块,因此,一个表仅有一个聚簇索引
表中的物理顺序和索引中行物理顺序是相同的,在创建一个非聚簇索引之前创建一个聚簇索引,这是因为聚簇索引改变了表中行的物理顺序,数据行 按照一定的顺序排列,并且自动维护这个顺序
聚簇索引默认是主键,如果表中没有定义主键,InnoDB会选择一个唯一的非空的索引代替,如果没有这样的索引,InnoDB会隐式定义一个主键来作为聚簇索引
MyISAM使用的是非聚簇索引
6.1.3、主键索引建议使用自增id,最好不要使用uuid,不适于排序,导致维护成本较高
6.2、主键索引 (PROMARY KEY)
也简称主键。它可以提高查询效率,并提供唯一性约束。一张表中只能有一个主键。被标志为自动增长的字段一定是主键,但主键不一定是自动增长。一般把主键定义在无意义的字段上(如:编号),主键的数据类型最好是数值。
小tis
6.3、普通索引(NORMAL)
6.4、唯一索引(UNIQUE)
索引的值不能重复
6.5、全文索引(FULLTEXT)
基本不用,一般用ES或者Solar,
6.6、空间索引(SPATIAL)
了解,知不知道无所谓。
6.7、复合索引(联合索引)重要
创建复合索引语句
//创建复合索引
create index idx_dept_id on test(dept_id,id,name);
当我们有多个查询条件的时候,我们推荐使用 复合索引。索引的组合使用
效率低于复合使用
比如:我们按照A列、B列、C列进行查询,通常的做法就是建立一个**由三个列共同组成的复合索引 **而不是每一列建立的普通索引。
为什么使用联合索引?
减少开销:建一个联合索引(GTd,Cid,STd)
,实际相当于建了(Gd)、(Gid,cid)、(Gid,cid, STd)
三个索引。每多一个索引,都会增加写操作的开销和磁盘空间的开销。对于大量数据的表,使用联合索引会大大的减少开销!
覆盖索引:对联合索引(Gid , cid ,Szd)
,如果有如下的sgl: select Gid,cid ,sId
from student where Gid
=1 and cid
=2。那么MSQL可以遍历索引取得数据,而无需回表,这减少了很多的随机ig操作。减少ig操作,特别的随机ig其实是ba主要的优化策略。所以,在真正的实际应用中,覆盖索引是主要的提升性能的优化手段之一
slect a,b,c from table where a=1 and b=2 and c=3;
效率高:索引越多,通过索引筛选的数据就越少。
缺点:联合索引越多,索引列越多,索引是存在于磁盘上的,通过索引算法来查找数据,的确可以提速,但是增删改
需要更新索引,同样需要花费很多时间,并且索引所占的磁盘也不小
建议:单表尽可能不要超过一个联合索引,单个联合索引不超过三个。
联合查询注意事项:
- 把范围查询的字段放在最后面。(最左匹配原则)
6.8、hash索引
create index name using hash on table(id);
无序,但是查询很快。
搜索引擎必须是memory/heap才支持hash索引。
二、mysqlUI建立索引
三、EX->mysql 用kettle
四、使用索引的问题
1、创建索引
1.1、哪些情况下适合建立索引
1.频繁作为where条件查询的字段适合做索引。
2.关联字需要建立索引,例如字段:student中的classid、classes中的schoolid等。
3.排序字段可以建立索引。
4.分组字段可以建立索引,因为分组的前提是排序。
5.统计类的字段可以作为索引,例如:count(),max()
1.2、哪些情况下不适合建立索引
1.频繁更新的字段不建议建立索引
2.where后用不到的字段不适合做索引
3.表数据可以确定较少的不适合做索引
4.数据重复且发布均匀的比较均匀的字段不适合做索引
5.↑即唯一性太差的字段,例如:性别,真假值
6.参与计算列的字段,索引会失效
1.3、索引不会包含有null值的列
1.单列索引无法存储null值,复合索引无法全为null值
2.查询时,is null条件,不能利用到索引,只能全盘扫描
3.索引是有序的
4.可以理解是树状存储,是区间嘛。
1.4、尽量使用短索引
1.尽量不重复
2.www.baidu.com 和 www.xinlang.com 的比较3个w可以不要啦
1.5、mysql索引失效的几种情况(重要)
- **如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)要想使用or , 又想让索引生效,只能将or条件中的每个列都加上索引 **
- 复合索引不能满足最左原则的就不能使用索引
- like查询以%开头的索引会失效
- 如果mysql估计使用全表扫描要比使用索引快,不走索引
- 参与列计算,索引会失效
五、索引分类总结
根据索引的方法(数据结构):
- hash索引
- B+Tree
根据索引的类型:
- 全文索引
- 普通索引
- 空间索引
- 唯一索引
根据索引和不和数据在一起
- 聚簇索引
- 非聚簇索引
六、Explain关键字
explain关键字可以模拟MySQL优化器执行SQL语句,可以很好的分析SQL语句或表结构的性能瓶颈。(显示执行语句的细节)
6.1、explain的用途
- 表的读取顺序如何
- 数据读取操作有哪些操作类型
- 哪些索引可以使用
- 哪些索引被实际使用
- 表之间如何引用
- 每张表有多少行被优化器查询
6.2、explain的执行效果
6.2.1、id字段(决定读表顺序)
1、id字段相同
执行顺序自上而下
2、id字段不同
如果是子查询,id的序号会递增,id的值越大优先级越高
3、id字段有相同有不同
id相同可能为一组,自上而下,不同的haul,按优先级大的先执行
6.2.2、select_type字段
1、simple
简单查询,不包含子查询或者union查询
2、primary
查询中若包含任何复杂的子部分,最外层查询则被标记为主查询
3、subquery(子查询)
在select或者where中包含的句子
4、deriver(接触了在了解)
在from列表中包含的子查询,被标记为derived(衍生),mysql会递归执行这些子查询,把结果放在临时表中
5、union
若后面使用了union,则后面被标记为union
6、union result
从union表获得结果的select
6.2.3、type字段(速度:快->慢)
1、NULL
MySQL能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引,比如通过id没有找到
2、system(用得少)
表中只有一行数据(等于系统表),这是const的特例, 平时不大会出现,可以忽略
3、const
表示索引一次就找到了,找到一条记录。const用于比较primary key或者uique索引,因为只匹配一行数据,所以很快。
4、eq_ref
唯一性索引扫描,对于每个索引键,表中只有一条数据与之匹配,常用于主键或者唯一索引扫描
5、ref
非唯一性索引扫描,一个索引 查询到 一群数据,
6、ref_or_null
类似于和ref,但是可以搜索到null值的行。
7、idx_merge
索引覆盖
8、range
范围查询
9、index(全索引扫描)
index只遍历索引树,比all快。
10、all(全表扫描)
将遍历全表,找到匹配行
11、总结
- const 唯一索引定值查
- ref 普通索引定值查
- range 索引范围查
- index 索引全扫描
- all 全表扫描
6.2.4、table
来源那张表
6.2.5、possible_keys
可能用到哪个索引
6.2.6、key
实际用了哪些索引
6.2.7、key_len字段
索引长度