MySQL索引

1.索引(index)是帮助MySQL高效获取数据数据结构(有序)。

2.MySQL为什么选择B+树,而不选二叉树或者红黑树?

首先我们来了解一下二叉树,二叉树在插入数据的时候是顺序插入的,假如我们插入的是一个有序的数组,这时,二叉树其实就是一个链表,如果我们要查的数据刚好是最底层的那个,查询次数依然是n,查询效率依然很差;再来说一下红黑树,红黑树本质也是一个二叉树,我们通常也称红黑树为二叉平衡树,红黑树有效地解决了有序数组顺序插入的问题,但是,当数据量足够大时,红黑树的节点就会变得很多,层级很深,检索效率依然不高。

 红黑树上存在的问题就是大数据量的时候,检索效果不理想,这时候我们就想到,能不能在一个节点上存多个数据呢?这样,不就解决了红黑树层级太深的问题了吗?这时候就产生了B树,B树在一个节点上存储多个数据,有效地减少了层级。

那MySQL选择的是B树吗?答案是否定的。相对于B树,InnoDB选择的是B+树。从B树的结构我们可以看出,B树是在每一个节点存储数据的,每个节点都是存放在页(page)中的,而页的大小固定为16K,如果我们在页中只存放索引,而不存放数据,我们就能存放更多的索引,可以把层级做得更少,检索效率更高。显然,相同大数据量的情况下,B树的层级会比B+树更多,索引效果更差。

B+树的特点是所有节点都存在于叶子节点,非叶子节点只做索引,不存储数据,只有叶子节点才存储数据,这样,在同一页中就能存放更多的索引。此时的B+还只是一个单向链表的结构。

 但B+树还不是最佳方案,MySQL对B+树进一步优化,增加了双向链表,提高了区间访问的性能。

 3.hash索引

hash索引是采用特定的hash算法,将键值换算成hash值,映射到对应的槽位上,然后存储在hash表中。当进行检索时,如果不考虑存在hash碰撞的情况下,hash检索的效率O(1),检索效率高于B+树。

当存在hash碰撞时,hash索引的检索效率要加上链表查询,这时候就不是O(1)了。

hash索引不支持范围查询,只支持等值匹配。

hash索引也不支持排序操作。

4.索引的分类

①如果表存在主键,则主键索引就是聚集索引;

②如果表不存在主键,但存在唯一索引,则第一个唯一索引是聚集索引;

③如果表不存在主键,且不存在唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引

5,回表查询

如上图所示,上方的索引是聚集索引,下方是二级索引。聚集索引的叶子节点存放的是行数据(row),而二级索引叶子节点存放的是字段对应的主键id。通过二级索引查询时,二级索引会先查询对应的主键id,然后回到聚集索引,通过id查到对应的行数据,这样的过程我们称为回表查询。这就是为什么主键索引查询通常优于一般索引查询的原因。 

6.InnoDB主键索引的B+树高度为多高?

一页大小是固定16K,假设一条数据1K,则一页可以存放16条数据;指针占6个字节,主键我们假设为bigint为8个字节,指针比主键多一个(估算忽略不计),公式为n=(16*1024)/(6+8),n约等于1170,则指针为1171个。当树的高度为2的时候,树最多可以存放可以存放1171*16=18736,当树的高度为3时,树最多可以存放1171*1171*16=21939856条数据。

当然,这一切都是基于假设,你可能会说,我数据如果不止1K呢?我主键的数据类型如果不是bigint呢?这就是为什么你们公司的DB不建议你们使用UUID作为主键索引,而强烈要求你们使用自增id作为主键索引的原因。这个假设是基于规范的假设,影响因素只在数据大小的差异,但三层的B+树几乎可以满足所有的数据要求,因为如果数据量再大点,我们通常就会考虑分库分表的操作了,这是后话了;如果有人非要钻牛角尖,那就再加一层上去呗。

7.索引的语法

7.1、创建索引

create [unique|fulltext] index index_name on table_name (index_col_name,...);
--[unique|fulltext]可加可不加,指定索引类型;
--index_name索引名称;
--table_name表名,其后接字段名,可以是一个字段,也可是多个字段

7.2、查看索引

show index from table_name;

7.3、删除索引

drop index index_name on table_name;

以下为创建索引及查看索引的展示

 

8.SQL性能分析

8.1.查看SQL的执行频率

show global status like 'Com_______';
--一共有7个下划线‘_’

圈出来的这几个是不是很熟悉,我们一眼就能看出,我们主要执行的select操作,目标是当前数据库。 

8.2、慢查询日志

慢查询日志记录所有执行时间超过指定参数(long_query_time,默认10S,且默认没开启)的所有SQL语句的日志。在MySQL的配置文件(/ect/my.cnf)中开启。

 

在配置文件中加上

#开启慢查询日志
slow_query_log=1
#设置超时记录时间,执行超过5秒记录
long_query_time=5

8.3、profile详情

show profiles能够在做SQL优化时帮助我们了解具体耗时,通过have_profiling参数可以查看当前MySQL是否支持profile操作。

profiling默认是关闭的,接着我们要去打开它。

 接着我们看一下如何使用profile;

--查看所有sql的耗时
select profiles;

--查看指定query_id的SQL语句各个阶段的耗时情况
show profile for query query_id;

--查看指定query_id的SQL语句cpu使用情况
show profile cpu for query query_id;

我们可以清楚看到我执行的三条sql的耗时,user表我给id建了索引,第三条执行效率明显优于第四条,这不是这里要讲的,就此打住,我们看一下第三条各个阶段的耗时情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值