【Java面试】四、MySQL篇(上)

在这里插入图片描述

文章目录

  • 1、定位慢查询
  • 2、慢查询的原因分析
  • 3、索引
    • 3.1 数据结构选用:二叉树 & 红黑树
    • 3.2 数据结构选用:B+树
  • 4、聚簇索引、非聚簇索引、回表查询
    • 4.1 聚簇索引、非聚簇索引
    • 4.2 回表查询
  • 5、覆盖索引、超大分页优化
    • 5.1 覆盖索引
    • 5.2 超大分页处理
  • 6、索引的创建
  • 7、索引的失效
  • 8、SQL优化的经验
  • 9、面试

1、定位慢查询

  • Arthas在线查看方法耗时
  • 运维工具Prometheus
  • 链路追踪工具Skywalking、Zipkin、OpenTemplate

在这里插入图片描述

  • MySQL自带的慢日志:记录执行超过n秒的SQL
//修改配置文件,文件位置
/etc/my.cnf//开启慢查询开关,生产环境不建议开启,会损失部分性能
slow_query_log=1//设置超过2秒的SQL
long_query_time=2

慢SQL被记录到/var/lib/mysql/localhost-slow.log

在这里插入图片描述

2、慢查询的原因分析

慢SQL通常是因为:

  • 聚合查询
  • 多表查询
  • 表数据量过大查询
  • 深度分页查询

前三种,可尝试使用SQL执行计划分析原因:

# SELECT语句前添加EXPLAIN或DESC,查看SQL语句执行情况的信息
EXPLAIN select * from t_table;
DESC select * from t_table;

在这里插入图片描述
此时SELECT返回的不是表数据,是一些执行信息:

  • possible: key 当前sql可能会使用到的索引
  • key: 当前sql实际命中的索引
  • key_len: 索引占用的大小,key和key_len搭配,检查是否存在索引失效
  • Extra:额外的优化建议

在这里插入图片描述

  • type:这条sql的连接的类型,性能由好到差为NULL、system、const、eq_ref、ref、range、index、all
system:查询MySQL系统内置库的表const:根据主键查询eq_re:主键索引查询或唯一索引查询ref:索引查询range:范围查询index:索引树扫描,遍历整个索引all:不走索引,全盘扫描

3、索引

一种用于高效查数据的数据结构,以某种方式指向表里的数据。如下表,不加索引,查age=45的数据,就是逐行对比 + 遍历整个表直至最后一行,效率低下

在这里插入图片描述

如果去维护一个类似二叉树的结构,再查age=45的数据,则直接从根节点开始⇒ 45 > 36,去右侧 ⇒ 45 < 48 ⇒去左侧 ⇒ 查找完毕,如此,查找效率提升,这即索引的思想

3.1 数据结构选用:二叉树 & 红黑树

MySQL索引底层的数据结构是B+树。不选二叉树是因为:

在这里插入图片描述
如果数据递增或递减,此时二叉树变链表,即最坏情况的二叉树效率很低。既然二叉树有平衡性问题,那再考虑自平衡的二叉树 ⇒ 红黑树

在这里插入图片描述

红黑树时间复杂度为O(log n),但其也是一个二叉树,每个节点最多只能两个分支,因此,大数据量下,红黑树会很高。 ⇒ B树,每个节点可以多个分支,是一种多叉路衡查找树。以一颗5阶B树为例(最大度数mas-degree为5,每个节点最多存储4个key)

在这里插入图片描述

图中的灰色部分,存储指针,指向子节点。如20左侧的指针,指向的就是20以内的数据,20和30之间的指针,则指向20~30之间的数据,以此类推。且绿色部分存储的是对应的那条数据。

3.2 数据结构选用:B+树

相比二叉树,B树是一种矮胖树,B+树则是B树的一种优化,非叶子节点只存储指针,不存储数据。只有在叶子节点才去存储对应的数据,前面的非叶子节点起一个导航的作用,非叶子节点上就匹配到的数据,在叶子节点上也能找到这个数。

在这里插入图片描述

MySQL默认的存储引擎InnoDB默认使用B+树实现索引。相比B树,B+树:

  • 磁盘读写代价更低(只有叶子节点存数据)
  • 查询效率更稳定(最后都要落到叶子节点)
  • 适合于区间查询(叶子节点之间的双向指针,比如查6~34这个区间的数,先从根节点对比,走左边,到16,再走左边,到6,再跟双向指针拿到6到34的数据,不需要再从根节点开始重新找一次

4、聚簇索引、非聚簇索引、回表查询

4.1 聚簇索引、非聚簇索引

聚簇索引(又叫聚集索引),即B+树的叶子节点保存的是整行数据。非聚簇索引(又叫二级索引),即B+树单独叶子节点存储的是那行数据对应的主键

在这里插入图片描述
聚簇索引选取规则:(节点里存哪个)

  • 如果存在主键,主键索引就是聚集索引
  • 如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引
  • 如果表没有主键,或没有合适的唯一索引,则InnoDB 会自动生成一个rowid 作为隐藏的聚集索引

如下:建立聚簇索引时,这张表有主键ID,因此,节点中存储的是ID值,最后,叶子节点中存的那个row是整条数据值。

在这里插入图片描述

再比如给表的name字段建立非聚簇索引,节点存储name的值,最后的叶子节点,存储的是这条数据的主键值

4.2 回表查询

select * form user where name = 'Arm';

给name字段加了非聚簇索引,因此,执行如上SQL,先根据name的非聚簇索引的B+树 ⇒ A小于L,走左边,到G和J,再走左边,找到Arm ⇒ 因为是select *,而非聚簇索引的叶子节点存的是主键 ⇒ 拿着主键,回到聚簇索引,从其根节点开始查 ⇒ 聚簇索引的叶子节点存了整行数据,返回select * 的结果

在这里插入图片描述

总之,回表查询就是:先根据非聚簇索引找到主键值,再根据主键值到聚簇索引拿到整行数据

5、覆盖索引、超大分页优化

5.1 覆盖索引

即查询使用了索引,并且你需要返回的字段,在索引中能够全部找到。

在这里插入图片描述

select * form tb_user where id = 1;

是覆盖索引,虽然select * ,但其where是根据id过滤的,即用的是主键索引、聚簇索引,索引的叶子节点存了整行数据,需要返回的字段,在索引中能够全部找到

在这里插入图片描述

select id, name from tb_user where name = 'Arm';

是覆盖索引,where根据name过滤,走name的非聚簇索引,最后叶子节点存了id,而最后需要返回的就是id和name

在这里插入图片描述

select id, name, gender from tb_user where name = 'Arm';

不是覆盖索引,索引中拿不到gender值,需要回表查询

在这里插入图片描述

很明显,能一次查询出来的,符合覆盖索引的,效率最高,走回表查询的SQL,效率低

5.2 超大分页处理

使用limit分页查,需要对数据进行排序,数据量很大时,效率很低

在这里插入图片描述

比如,limit 900 0000,10,此时,需要排序前9000010行数据,再返回9000000到9000010行这10行:

在这里插入图片描述

解决方案是:覆盖索引 + 子查询

在这里插入图片描述
即先根据主键去分页order by id ,不select *,而是select id,再和原来的表关联查

6、索引的创建

需要创建索引的场景:

  • 数据量大(单表超过10万行),且查询频繁
  • 给常作为where、order by、group by操作的字段创建索引
  • 如果字段是字符串类型,且长度很长,给其建立索引压力大,可截取前几个字,建立前缀索引

在这里插入图片描述

  • 多用联合索引,而不是单列索引。因为如果给A + B两个字段建立了联合索引,刚好又select A, B from table where A = 1;就是覆盖索引,避免了回表,查询效率更高。下图即给name、status、address三个字段建了联合索引

在这里插入图片描述

  • 索引并不是越多越好,因为增删改也要同步去维护索引,索引多了,会影响增删改的效率

7、索引的失效

给表tb_seller的name,status,address字段创建联合索引:

在这里插入图片描述
索引失效的场景:

1)违反最左前缀法则

最左前缀法则,即select后面的字段,必须从索引的最左前列开始,并且不跳过索引中的列。以下为索引不失效的写法:

在这里插入图片描述

以下写法索引失效:
在这里插入图片描述
以下写法,中途跳过了联合索引的某一列,只有最左侧字段索引生效,从key_len的大小可以看出,其只命中了一个字段:

在这里插入图片描述

2)对status范围查询,则status右边的列address没有用到索引,但name,status还是走了索引了

在这里插入图片描述

3)在索引所在的列上进行运算,索引会失效

在这里插入图片描述

4)字符串不加单引号,索引失效

因为不对字符串类型加单引号,MySQL优化器会自动进行类型转换,造成索引失效
在这里插入图片描述

5)以%开头的Like模糊查询,索引失效

注意:如果仅仅是末尾进行模糊查询,索引不会失效

在这里插入图片描述

8、SQL优化的经验

1)表设计优化:

  • 设置合适的数值类型:tinyint、int、bigint
  • 字符串类型,char和varchar,char定长、效率高,varchar长度灵活可变,根据字符串实际长度来,但效率稍低

在这里插入图片描述

2)SQL语句优化

  • 避免select *
  • 避免索引失效的写法
  • 使用union all代替union,union会把两个查询的结果再做个去重

在这里插入图片描述

  • 避免where中对字段进行计算操作
  • join表时,能用inner join,不left join或者right join,业务必须要用时,可将小表(行数少的表)放外面。原因参考for循环嵌套,如下写法,MySQL进行三次连接,每次连接进行1000次操作,反之就是进行1000次连接,每次连接进行3次操作(inner join 就会自动优化,把小表放外面。left join或right join就不会把小表放外面)

在这里插入图片描述
3)读写分离,主从复制

  • 用于避免写操作影响查询效率
  • 主库写,从库读

在这里插入图片描述
4)索引的创建和失效
5)分库分表(见下篇)

9、面试

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

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/17382.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

联发科MT8370平台Genio 510物联网应用程序处理器详细规格参数

MT8370是一款高度集成、功能强大的平台&#xff0c;专为各种人工智能(AI)和物联网(IoT)用例而设计&#xff0c;这些用例需要高性能边缘处理、先进的多媒体和连接功能、多个高分辨率摄像头、连接的触摸屏显示器以及多任务高级操作系统(HLOS)的使用。http://Genio 510 (MT8370) E…

Mybatis源码剖析

文章目录 一、前置1.1概念ORMSqlSession会话 二、快速入门2.1 SpringBoot整合Mybatis2.2 XML配置2.2.1 路径位置2.2.2 名称2.2.3 configuration标签内容环境environments标签映射器mappers标签 2.3 Mapper接口2.3.1 单Mybatis项目2.3.2 SpringBoot整合mybatis2.3.3 m整合mybati…

字符串函数(2)<C语言>

前言 快一周没更博客了&#xff0c;最近有点忙&#xff0c;今天闲下来了&#xff0c;还是不行&#xff0c;继续干&#xff0c;书接上回继续介绍字符串函数&#xff1a;strncpy()、strncat()、strcmp()、strtok()使用、strstr()使用以及模拟实现、strerror()使用。 strncpy()、s…

揭秘网络编程:同步与异步IO模型的实战演练

摘要 ​ 在网络编程领域&#xff0c;同步(Synchronous)、异步(Asynchronous)、阻塞(Blocking)与非阻塞(Non-blocking)IO模型是核心概念。尽管这些概念在多篇文章中被广泛讨论&#xff0c;它们的抽象性使得彻底理解并非易事。本文旨在通过具体的实验案例&#xff0c;将这些抽象…

在React中使用Sass实现Css样式管理-10

0. 什么是Sass Sass(Syntactically Awesome Stylesheets)是一个 CSS 预处理器&#xff0c;是 CSS 扩展语言&#xff0c;可以帮助我们减少 CSS 重复的代码&#xff0c;节省开发时间&#xff1a; Sass 引入合理的样式复用机制&#xff0c;可以节约很多时间来重复。支持变量和函…

C++之“流”-第2课-C++和C标准输入输出同步

为什么C和C的标准输入输出不同步时&#xff0c;数据会混乱&#xff1f;同步会带来多大性能损失&#xff1f;为什么说这个损失通常不用太在乎&#xff1f; 0. 课堂视频 C之“流”-第2课&#xff1a;和C输入输出的同步 1. 理解cin和cout的类型与创建过程 std::cout 是std::ostre…

添加、修改和删除字典元素

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 由于字典是可变序列&#xff0c;所以可以随时在字典中添加“键-值对”。向字典中添加元素的语法格式如下&#xff1a; dictionary[key] value 参数…

You don‘t have enough free space或者no space left on device异常

1.磁盘空间不足 Linux安装软件显示 You dont have enough free space 或者docker拉镜像时&#xff0c;出现磁盘空间不足的情况 no space left on device 如果你是ubuntu系统。查看磁盘空间 df -h 多半是这个目录满了/dev/mapper/ubuntu--vg-ubuntu--lv 大多情况我们只希望扩…

学习编程对英语要求高吗?

学习编程并不一定需要高深的英语水平。我这里有一套编程入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习编程&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&#xff0c;我在后台发给你。 虽然一些编程资源和文档可能…

typora自动生成标题序号(修改V1.0)

目录 带序号效果图 解决方法 带序号效果图 解决方法 1.进入文件夹&#xff1a;文件–>偏好设置–>外观–>主题–>打开主题文件夹 2.如果没有base.user.css文件&#xff0c;新建一个。如果有直接用记事本打开&#xff0c;把下面代码拷贝进去保存。 /** initiali…

【JUC编程】-多线程和CompletableFuture的使用

多线程编程 文章目录 多线程编程[toc]引言创建多线程的方式继承Thread类实现Runnable接口实现Callable接口Callable和Runnable的区别 Lambda表达式 线程的实现原理Future&FutureTask具体使用submit方法Future到FutureTask类Future注意事项局限性 CompletionService引言使用…

第八大奇迹

目录 题目描述 输入描述 输出描述 输入输出样例 示例 输入 输出 运行限制 原题链接 代码思路 题目描述 在一条 R 河流域&#xff0c;繁衍着一个古老的名族 Z。他们世代沿河而居&#xff0c;也在河边发展出了璀璨的文明。 Z 族在 R 河沿岸修建了很多建筑&#xff0c…

Ps 滤镜:消失点

Ps菜单&#xff1a;滤镜/消失点 Filter/Vanishing Point 快捷键&#xff1a;Ctrl Alt V 两条平行的铁轨或两排树木连线相交于很远很远的某一点&#xff0c;这点在透视图中叫做“消失点”&#xff0c;也称为“灭点”。 消失点 Vanishing Point滤镜主要用于在图像中处理具有透视…

C++入门3——类与对象(2)

1.类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。可是空类中真的什么都没有吗&#xff1f; 其实并不是的&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 默认成员函数&#xff1a;用户没有显式实现&#xf…

libmodbus开发库介绍

目录 功能概要源码获取源码内容结构源码与移植 功能概要 libmodbus是一个免费的跨平台支持RTU和TCP的Modbus库&#xff0c;遵循LGPL V2.1协议。libmodbus支持Linux、Mac Os X、FreeBSD、QNX和Windows等操作系统。libmodbus可以向符合Modbus协议的设备发送和接收数据&#xff0…

《Python侦探手册:用正则表达式破译文本密码》

在这个信息爆炸的时代&#xff0c;每个人都需要一本侦探手册。阿佑今天将带你深入Python的正则表达式世界&#xff0c;教你如何像侦探一样&#xff0c;用代码破解文本中的每一个谜题。从基础的字符匹配到复杂的数据清洗&#xff0c;每一个技巧都足以让你在文本处理的领域中成为…

系统思考—战略沙盘推演咨询服务

今日与JSTO团队一起学习了《战略沙盘推演咨询服务》。通过沙盘体验&#xff0c;我深刻感受到组织与战略就像一张皮的正反两面。在转型过程中&#xff0c;即使战略非常明确&#xff0c;团队成员由于恐惧和顾虑&#xff0c;往往不愿意挑战新的业务&#xff0c;从而难以实现战略目…

VasDolly图形工具-Android多渠道打包福利

简介 基于腾讯VasDolly最新版本3.0.6的图形界面衍生版本&#xff0c;旨在更好的帮助开发者构建多渠道包 使用 下载并解压工具包&#xff0c;找到Startup脚本并双击启动图形界面&#xff08;注意&#xff1a;本地需安装java环境&#xff09; 渠道格式说明 txt文件&#xff…

Qt | QTabBar 类(选项卡栏)

01、上节回顾 Qt | QStackedLayout 类(分组布局或栈布局)、QStackedWidget02、简介 1、QTabBar类直接继承自 QWidget。该类提供了一个选项卡栏,该类仅提供了一个选项卡, 并没有为每个选项卡提供相应的页面,因此要使选项卡栏实际可用,需要自行为每个选项卡设置需要显示的页…

山东大学软件学院项目实训-创新实训-基于大模型的旅游平台(二十一)- 微服务(1)

微服务 1.认识微服务 SpringCloud底层是依赖于SpringBoot的&#xff0c;并且有版本的兼容关系&#xff0c;如下&#xff1a; 2. 服务拆分 需求 &#xff1a; 把订单信息和用户信息一起返回 从订单模块向用户模块发起远程调用 &#xff0c; 把查到的结果一起返回 步骤 &…