mysql的进阶学习--应用篇--索引

安装Linux版本的mysql

系统: centOS7
msyql: 8.0.26

索引概述

索引是一种有序的数据结构
可以帮助MySQL高效的获取数据.

那也就是说: 在数据库表结构之中, 除了要保存数据之外, 数据库还要去维护索引这种数据结构, 利用这些结构指向保存的数据. 这样就可以在这些数据结构中通过高级的查找算法, 快速定位到原始数据.
在这里插入图片描述
在这里插入图片描述

索引结构

MySQL的索引是在存储引擎层中实现的, 不同的存储引擎有不同的结构, 主要包含以下几种:
在这里插入图片描述

二叉树索引结构

在这里插入图片描述
改良:
在这里插入图片描述
在这里插入图片描述

B-tree索引结构

以一颗最大度数为5的b-tree为例(每一个节点最多存储4个key, 5个指针)
在这里插入图片描述

B+tree索引结构

所有的元素只在叶子节点, 在上边的都只是起到索引的用处.
叶子节点形成了一个单向链表.
在这里插入图片描述
在这里插入图片描述

Hash索引结构

在这里插入图片描述
hsah索引的特点:
只能用来对等比较, 不支持范围查询;
无法利用索引完成排序;
查询效率高于B+tree;

在mysql中, 支持hash索引的引擎是, memory引擎, 而InnoDB中具有自适应hash功能, hash索引是存储引擎根据B+tree在指定条件下自动构建的.

为什么是B+tree

在这里插入图片描述

索引分类

按功能分类

在这里插入图片描述

按存储形式分类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

小结

在这里插入图片描述
可以发现, Innodb的表即使存放两千多万条记录, 也才三层. 效率是很高的.
那如果有上亿的记录啦, 那就得考虑分库分表啦~

索引语法

创建索引

create [union | fulltext] index 索引名 on 表名 (字段名,..);

注意:

如果一个索引关联了一个字段, 那么就叫单例索引
如果关联了多个索引, 那么就叫联合索引或者组合索引.

注意:

组合索引的字段顺序是有讲究的.

查看索引

show index from 表名;

删除索引

drop index 索引名 on 表名;

SQL性能分析

为什么要学SQL性能分析工具

我们为什么要学习性能分析工具, 因为要做SQL优化, 那么就要能够定位出要对哪一类的SQL进行优化, 这个时候, 我们就要知道每一种SQL的性能是怎么样的.

而实际上, 主要要优化的就是查询语句.
而在优化查询语句的时候, 索引其实占了主导地位.

查看执行频次

为什么要知道SQL的执行频率:
假如说, 有一个业务系统, 有一个数据库的一些表的数据量特别大, 但是这张表我只做插入, 不做查询. 此时, 这张表并不需要做优化.

所以我们要根据SQL的执行频率来判定, 当前数据库是以查询为主还是以增删改为主, 我们要能看到增删改查在当前数据库所占的比例.

show [session|global] status 命令可以提供服务器的状态信息, 通过如下命令, 可以查看当前数据库的Insert, update, delete, select的访问频次.

  • session 就是会话的状态信息
  • global 就是全局的状态信息

show global status like 'com_______';(这里要七个下划线, 代表七个字符)

慢查询日志

也叫做优化慢查;
如果说我们已经确认了, 当前数据库当中, select语句的频次是最大的, 也就是说需要优化, 那么应该是优化哪些SQL语句呢?

慢查询日志来定位SQL语句, 哪些SQL语句执行效率比较低, 从而对这类的语句进行优化,

慢查询日志记录了所有执行时间超过指定参数(long_query_time, 单位:秒, 默认10秒)的所有SQL语句的日志.

MySQL的慢查询日志默认没有开启, 需要在MySQL的配置文件中(Linux下是/etc/my.cnf)中配置如下信息.
查看慢查的开关
show variables like 'slow_query_log';(默认没有开启)
在这里插入图片描述
vi /etc/my.cnf
systemctl restart mysqld
cd /var/lib/mysql
ll
找到localhost-slow.log
cat localhost-slow.log(查看内容)
tail -f localhost-slow.log(查看尾部实时)
在这里插入图片描述

show profiles

通过慢查就可以定位到哪些sql语句执行超过了2秒需要被优化
有些语句的业务很简单, 但是他的执行达到了1.9几秒.
这类的SQL事实上也算性能低
那么怎么定位到这一类的SQL呢?
慢查满足不了, 就要利用这种手段, 叫做profile详情

show profiles 指令能够在做SQL优化时帮助我们了解时间都耗费到哪些地方去了, 通过have_profiling 参数, 能够看到目前MySQL是否支持profile操作.
select @@have_profiling;(默认是关闭的)
可以通过set语句在session/global级别开启profiling.
set [session|global] profiling = 1;

基本用法就是:
执行一系列的业务SQL的操作, 然后通过如下的指令查看指令的执行耗时:
查看每一条业务SQL的耗时基本情况:
show profiles;
查看指定query_id的SQL语句各个阶段的耗时情况
show profile for query query_id;
查看指定query_id的SQL语句CPU的使用情况
show profile cpu for query query_id;

explain

以上都是在时间的层面, 什么执行频率, 执行时间过长, 执行的耗时情况等等, 都还不能真正的评判一条SQL语句的性能, 我们想看一条语句的性能, 还需要看第四种手段, explain, 来查看SQL语句的执行计划.

explain在SQL优化中, 占据这十分重要的地位, 我们经常是通过的他判定SQL语句的性能. 获取它的执行计划, 在它的执行过程中是否用到了索引, 表的连接情况, 表的连接顺序都可以看到.

语法:
直接在select语句之前家伙加上关键字, explain/desc
explain select 字段列表 from 表名 where 条件;

在这里插入图片描述
如图: 可以看到的信息有:

  • id: 指代的是SQL语句中表的执行顺序. 表示的是查询中执行select子句或者操作表的顺序(id相同, 执行顺序从上到下, id不同, 值越大, 越先执行), 说白了, 就是使用于多表查询.
  • select_type: 表示select的类型, 常见的取值有simple(简单表, 即不用表连接或者子查询), primary(主查询, 即外层的查询), union(union中的第二个或者后面的查询语句), subquery(select/where之后包含了子查询)等. 说白了, 就是表示当前这条查询语句的查询类型.
  • (重点)type: 表示访问的类型, 或者叫连接类型, 性能由好到差的性能类型为null, system, const, eq_ref, ref, range, index, all. 说白了, 也就是说使用主键或者唯一索引, 一般就是const, 就是业务实际中最好的性能了, null是不访问任何表, system是系统的表, 一般是优化不到这份上的.
  • (重点)possible_key: 可能用到的索引, 会显示可能应用在这张表上的索引, 一个或者多个.
  • (重点)key: 实际用到的索引; 如果为null, 则没有使用索引.
  • (重点)key_len: 索引的长度, 表示索引中使用字节数, 该值为索引字段的最大可能长度, 并非实际使用的长度, 在不损失精确性的前提下, 长度越短越好.
  • rows: mysql认为要执行查询的行数, 在innodb引擎的表中, 是一个估计值, 可能并不准确.
  • filtered: 表示返回结果的行数占需要读取的行数的百分比, filtered的值越大越好.
  • (重点)extra: 额外的信息.

索引使用

验证索引的作用

几个联合索引失效的法则

最左前缀法则

如果索引了多列, 也就是联合索引, 要遵守最左前缀法则, 最左前缀法则是指查询从索引的最左列开始, 并且不跳过索引中的列. 如果跳过了某一列, 索引将部分失效(后面的字段索引失效)

范围查询

如果联合索引中, 出现(>, <)这两种范围查询, 范围查询的右侧的列索引会失效. 所以, 尽量要用(>=, <=)

索引失效法则

不要在索引列上进行运算操作, 索引将失效.

字符串不加引号, 索引将会失效.

如果仅仅是尾部模糊匹配, 索引不会失效, 头部模糊, 完蛋

or两侧有一个不是索引, 都失效

数据分布影响, 如果Mysql评估使用索引比全表会更慢, 放弃索引

SQL提示

use:建议

ignore: 忽略

force: 强制

在这里插入图片描述

覆盖索引

尽量使用覆盖索引(查询使用了索引, 并且需要返回的列, 在该索引中已经全部能够找到), 减少select *;

前缀索引

当字段的类型是字符串(varchar, text)等时, 有时候需要索引很大的字符串, 这会浪费大量的磁盘IO, 影响查询效率, 此时可以之将字符串的一部分前缀, 建立索引, 这样可以大大节约索引空间, 从而提高索引效率.
在这里插入图片描述

单列索引和联合索引

索引设计原则

针对数据量较大, 且查询比较频繁的表建立索引.

如果一张表有一百多万条记录, 此时就要考虑建立索引.

针对于常作为查询条件的(where), 排序(order by), 分组(group by)操作的字段建立索引.

除了查询业务, 事实上, 增删改建立索引的意义不大. 而在这三个地方建立索引被使用的概率最高.

尽量选择区分度高的列作为索引, 尽量建立唯一索引, 区分度越高, 使用索引的效率越高.

例如性别, 状态这类字段, 建立索引意义也不大.

如果是字符串类型的字段, 字段的长度较长, 可以针对字段的特点, 建立前缀索引.

尽量使用联合索引, 减少单列索引, 查询时, 联合索引很多时候, 可以覆盖索引, 节省存储空间, 避免回表, 提高查询效率

要控制索引的数量, 索引并不是多多益善, 索引越多, 维护索引的代价就越高, 会影响增删改的效率.

如果索引列不能存储null值, 请在创建表时使用not null约束之, 当优化器知道每列是否包含null值时, 他可以更好的确定那个索引更有效的用于查询.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值