- m阶B树
大概定义:
- 根节点个数范围[1,m-1]
- 每个节点最多有m个孩子
- 所有叶子节点在同一层
- 节点内的值从大到小
- 叶子节点与非叶子节点都存放数据
详见:B树定义
- m阶B+树
大概定义:只有在叶子节点上存放数据,并且还有双向指针,指向大于或小于的数据
- 为什么使用B+树作为数据库索引的数据库结构
1. 相比于红黑树: 红黑树是一种自平衡二叉查找树,但是红黑树一个节点只能存放一个数据,这就会导致相同的数据量来说,红黑树的深度更深,而数据库的查询效率跟树的深度是息息相关的,所以红黑树效率更低。
2. 相比于B树:
效率: B树在叶子节点之上的节点均存放索引、数据及其指针,相比于B+树来说,B+树在非 叶子节点中存放的只有索引和指针,在内存上没有数据的损耗,所以对于相同大小的节点来说,B+树存放的索引信息更多,所以对于相同大小的存储空间,在B+树能保存更多的节点信息,所以相同的数据量来说B树的深度会更深,就可能会导致查询效率没有B+树那么高。并且在数据库的查询方面,I/O操作是主要耗费查找时间的,B+树因为只有叶子节点存放数据,所以在叶子节点之前的I/O操作效率是要更高的。
稳定性: B+树的查询会比B树更加稳定,是因为B+树的数据存保存在叶子节点中,始终会查询到叶子节点才会将查询的结果返回,是更加稳定的,B树因为查询的数据全覆盖,所以可能会出现快与慢的情况。
范围查询: 对于范围查询来说,因为B+树的数据均保存在叶子节点上,并且使用双向指针指向大于他的数据和小于他的数据,所以在找到id为1的节点之后,可以轻松找到id大于等于1的节点,相比于B树来说,B树在范围查找方面更弱,B树不能很好的遍历条件的范围。
1. 聚集索引
叶子节点中包含了全部的数据信息的索引称为聚集索引。InnoDB存储引擎类型的主键索引,是聚集索引。
2. 非聚集索引
叶子节点中不包含全部的数据信息,如果要查询全部的信息,需要回表。MyISAM存储引擎的主键索引是非聚集索引,主键索引只包含主键和地址,查询数据的时候,是先从Myi文件中找到对应索引的元素地址,然后再去Myd文件查找到对应的数据。
3. Hash索引
计算键的Hash值存入对应的桶中,一个桶可以存入多条数据。
优势: 对于单个匹配查找效率更高,可能计算Hash找到匹配的桶,桶中可能只有一个数据,可以很快定位到要查找的数据。
劣势: 对于范围查找不友好,因为范围查找通常是在有排序下更快的。
- rows列:查询必须要检查的行数(估计值)
- filtered列:返回的结果行数占查询总行数的百分比
- partition列: 会显示查询将访问的分区
在优化过程中用的很少,简要了解就行。
- id列:有几个select就有几个id值,并且id越大的select执行优先级越高,如果出现相同的id值,优先顺序则是按从上往下执行的,id为NULL的是最后执行的。
- table列:表示当前查询访问的哪个表,当from语句有子查询的时候,table列是<derivenN>,表示当前查询依赖 id=N 的查询,当有union的时候,table值为<union1,2>同理。
- select_type列:表示对应查询的查询类型
- type列:表示查询关联类型,表示MySQL决定如何查询表,查找数据行的大概范围。
最优到最差排序:system const eq_ref ref range index ALL
一般来说,得保证查询达到range级别,最好达到ref
system、const: const表示在mysql进行查询优化后,将其转化为了常量,通过执行show warnings可以查看到优化后的结果,直接将结果集写出来并从dual(空表)中查询,表中最多只有一个匹配行,读取速度是很快的。system是const的特例,当表中只有一条元素的时候的常量匹配为system。
eq_ref: 当用主键和唯一键索引与其他表连接时的类型,只有在关联的时候会出现,简答的select查询不会出现这种类型。
ref: 与eq_ref不同的是,ref类型使用的是非唯一索引或唯一索引的非唯一前缀,并且简单查询也可以是ref类型。
- 使用非唯一索引(简单查询)
2. 使用联合索引的非唯一前缀
range: 索引的范围匹配,出现在in(),between,>,<等操作类型中
index: 指全扫描二级索引才能得到结果,这种查询不会从索引树根节点开始查找,而是直接从叶子节点上遍历,这种查询一般为使用覆盖索引,因为二级索引与聚集索引相比,二级索引只包含了部分数据,所以在效率上是比聚集索引扫描效率更高的。
ALL: 指聚集索引全扫描,通常情况下需要添加索引来进行优化。
上面的两个例子(index、ALL)中,type类型不同是因为,film表的二级索引已经包含了需要查询的全部信息(film_name,id)所以mysql的优化中,如果判断可以走二级索引就优先走二级索引,而不走全索引,因为二级索引的效率肯定是要优于全索引的,而actor表中的二级索引并不包含全部的数据,所以最终选择了走聚集索引扫描。
- possible_keys列:表示在mysql内部的估算系统中认为可能使用的索引列,可能出现此列不为NULL,但key列为NULL的情况,这种情况通常是表中数据不多,mysql认为走索引对次帮助不大,不如直接走全表扫描,也会出现此列为NULL,但key不为NULL的情况。如果该列为空,则表示没有相关的索引,则可以考虑创建适合的索引来提高效率。
- key列:这列表示mysql实际采用了哪个索引。可以通过force index、ingore index来强制使用索引或忽略索引。
- key_len列:表示mysql索引使用的字节数,通常通过这个值我们可以判断出索引使用了哪些列
- ref列:用于记录使用索引所用到的常量或列,常见有const,字段名(例如film…id)
- Extra列:用于展示额外信息,信息值很多,而且不是很稳定。
- Using index: 使用覆盖索引
- Using where:使用where语句来处理结果,并且查询的列未被索引覆盖
- Using index condition:查询的列不完全被索引覆盖,where条件中是一个前导范围
我的理解是,索引中存在范围查询,并且最后还是走的索引的范围查找,不是走的全扫描可能出现的就是这种情况,比如下图不走索引的范围查找就是Using where
- Using temporary:指mysql需要创建临时表来处理查询,这种情况一般是要优化的,可以考虑创建索引。
- Using filesort: 使用的是文件排序,数据较小时从内存排序,否则需要在磁盘完成排序,一般考虑使用索引优化。
- Select tables optimized away: 使用某些聚合函数(比如max、min)来访问索引的某个字段
示例表:
2 不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),否则会导致索引失效转向全表扫描。
原因:使用索引得保证有序才能使用索引,截取部分索引,比如果截取name中的一部分无法在索引树上有序排列,所以无法使用索引。
日期类型索引如何使用:
3 使用索引的时候,尽量把范围查询放在索引的最右端,否则也会导致索引失效
联合索引中所有字段都用上了key_len是140
前置使用了范围查找,position字段的索引失效了。
改进: 修改联合索引,将age放在position的右边。
4 尽量使用覆盖索引(只访问包含索引列的查询),减少select * 语句,否则可能会造成索引失效
5 在使用范围查找时可能也会导致索引失效
改进想法: 对于大于某个数,可以考虑分段查询出来,然后再联合起来,可能会使查询效率变高。
6 like以通配符开头,也会是索引失效,转为全表扫描
可以考虑使用覆盖索引,将ALL优化为index
7 字符串不加单引号也会导致索引失效,因为会触发强制类型转换,跟使用函数同理
索引下推:对于辅助的联合索引,对于第一个字段如果是like 'xx%'匹配的,匹配完如果得到的数据量不是很大,会进行下推匹配找联合索引的其他字段是否匹配。
以上使用索引的key_len是140包含了联合索引的全部字段,就用到了索引下推。在mysql5.6之前的版本是没有索引下推的,在匹配了第一个字段name之后就会将查询的id进行回表操作再判断之后的字段是否匹配,在mysql5.6之后优化了索引下推,在name字段匹配之后,还会继续匹配age和position的字段,然后再将匹配的id进行回表查询,减少了回表的次数。但是索引下推也不是必然发生,如果前面的字段匹配的范围比较大,也不会进行索引下推了,mysql会认为直接进行回表效率更高。
查看mysql内部优化的结果:可以使用trace工具
使用trace工具查询
到此这篇treesizefree设置最佳配置(treesizefree怎么用)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/rfx/76772.html