【Java面试总结】MySQL篇·优化篇

news2024/9/22 21:35:38

【Java面试总结】MySQL篇·SQL优化篇

  • 1.该如何优化MySQL的查询?
  • 2.怎样插入数据才能更高效?
  • 3.表中包含几千万条数据该怎么办?
  • 4.MySQL的慢查询优化有了解吗?
  • 5.说一说你对explain的了解
  • 6.explain你一般关注什么?

1.该如何优化MySQL的查询?

使用索引:

如果查询时没有使用索引,查询语句将扫描表中的所有记录。在数据量大的情况下,这样查询的速度会很慢。如果使用索引进行查询,查询语句可以根据索引快速定位到待查询记录,从而减少查询的记录数,达到提高查询速度的目的。

索引失效的三种情况:

  1. 使用LIKE关键字的查询语句

在使用LIKE关键字进行查询的查询语句中,如果匹配字符串的第一个字符为“%”,索引不会起作用。只有“%”不在第一个位置,索引才会起作用。

  1. 使用多列索引的查询语句

MySQL可以为多个字段创建索引。一个索引可以包括16个字段。对于多列索引,只有查询条件中使用了这些字段中的第1个字段时索引才会被使用。

  1. 使用OR关键字的查询语句

查询语句的查询条件中只有OR关键字,且OR前后的两个条件中的列都是索引时,查询中才使用索引。否则,查询将不使用索引。

优化子查询:

使用子查询可以进行SELECT语句的嵌套查询,即一个SELECT查询的结果作为另一个SELECT语句的条件。子查询可以一次性完成很多逻辑上需要多个步骤才能完成的SQL操作。

子查询虽然可以使查询语句很灵活,但执行效率不高。执行子查询时,MySQL需要为内层查询语句的查询结果建立一个临时表。然后外层查询语句从临时表中查询记录。查询完毕后,再撤销这些临时表。因此,子查询的速度会受到一定的影响。如果查询的数据量比较大,这种影响就会随之增大。

在MySQL中,可以使用连接(JOIN)查询来替代子查询。连接查询不需要建立临时表,其速度比子查询要快,如果查询中使用索引,性能会更好。


2.怎样插入数据才能更高效?

影响插入速度的主要是索引、唯一性校验、一次插入记录条数等。针对这些情况,可以分别进行优化。

对于MyISAM引擎的表,常见的优化方法如下:

  1. 禁用索引

对于非空表,插入记录时,MySQL会根据表的索引对插入的记录建立索引。如果插入大量数据,建立索引会降低插入记录的速度。为了解决这种情况,可以在插入记录之前禁用索引,数据插入完毕后再开启索引。对于空表批量导入数据,则不需要进行此操作,因为MyISAM引擎的表是在导入数据之后才建立索引的。

  1. 禁用唯一性检查

插入数据时,MySQL会对插入的记录进行唯一性校验。这种唯一性校验也会降低插入记录的速度。为了降低这种情况对查询速度的影响,可以在插入记录之前禁用唯一性检查,等到记录插入完毕后再开启。

  1. 使用批量插入

插入多条记录时,可以使用一条INSERT语句插入一条记录,也可以使用一条INSERT语句插入多条记录。使用一条INSERT语句插入多条记录的情形如下,而这种方式的插入速度更快。

INSERT INTO fruits VALUES ('x1', '101', 'mongo2', '5.7'), ('x2', '101', 'mongo3', '5.7'), ('x3', '101', 'mongo4', '5.7');
  1. 使用LOAD DATA INFILE批量导入

当需要批量导入数据时,如果能用LOAD DATA INFILE语句,就尽量使用。因为LOAD DATA INFILE语句导入数据的速度比INSERT语句快。

对于InnoDB引擎的表,常见的优化方法如下:

  1. 禁用唯一性检查

插入数据之前执行set unique_checks=0来禁止对唯一索引的检查,数据导入完成之后再运行set unique_checks=1。这个和MyISAM引擎的使用方法一样。

  1. 禁用外键检查

插入数据之前执行禁止对外键的检查,数据插入完成之后再恢复对外键的检查。

  1. 禁用自动提交

插入数据之前禁止事务的自动提交,数据导入完成之后,执行恢复自动提交操作。


3.表中包含几千万条数据该怎么办?

建议按照如下顺序进行优化:

  1. 优化SQL和索引;
  2. 增加缓存,如memcached、redis
  3. 读写分离,可以采用主从复制,也可以采用主主复制;
  4. 使用MySQL自带的分区表,这对应用是透明的,无需改代码,但SQL语句是要针对分区表做优化的;
  5. 做垂直拆分,即根据模块的耦合度,将一个大的系统分为多个小的系统;
  6. 做水平拆分,要选择一个合理的sharding key,为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,sql中尽量带sharding key,将数据定位到限定的表上去查,而不是扫描全部的表。

4.MySQL的慢查询优化有了解吗?

优化MySQL的慢查询,可以按照如下步骤进行:

开启慢查询日志:

MySQL中慢查询日志默认是关闭的,可以通过配置文件my.ini或者my.cnf中的log-slow-queries选项打开

启动慢查询日志时,需要在my.ini或者my.cnf文件中配置long_query_time选项指定记录阈值,如果某条查询语句的查询时间超过了这个值,这个查询过程将被记录到慢查询日志文件中。

分析慢查询日志:

直接分析MySQL慢查询日志,利用explain关键字可以模拟优化器执行SQL查询语句,来分析sql慢查询语句。

常见慢查询优化:

1、索引没起作用的情况

2、优化数据库结构

  • 对于字段比较多的表,如果有些字段的使用频率很低,可以将这些字段分离出来形成新表。因为当一个表的数据量很大时,会由于使用频率低的字段的存在而变慢。
  • 对于需要经常联合查询的表,可以建立中间表以提高查询效率。通过建立中间表,把需要经常联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询,以此来提高查询效率。

3、分解关联查询

很多高性能的应用都会对关联查询进行分解,就是可以对每一个表进行一次单表查询,然后将查询结果在应用程序中进行关联,很多场景下这样会更高效。

4、优化LIMIT分页

当偏移量非常大的时候,例如可能是limit 10000,20这样的查询,这是MySQL需要查询10020条然后只返回最后20条,前面的10000条记录都将被舍弃,这样的代价很高。

针对这种问题,我们可以在每次查询分页时,前端返回一个上一次查询到的分页的最大值,之后的分页查询参考上一次查询的最大值进行查询

优化此类查询的另一个简单的方法是尽可能的使用索引覆盖扫描,而不是查询所有的列。然后根据需要做一次连接操作再返回所需的列。对于偏移量很大的时候这样做的效率会得到很大提升。

例如:(这是一个使用子查询的实例)

在这里插入图片描述


5.说一说你对explain的了解

EXPLAIN语句的基本语法如下:

EXPLAIN [EXTENDED] SELECT select_options

实例:

EXPLAIN SELECT * FROM tb_user;

在这里插入图片描述

下面对查询结果进行解释:

  • id:SELECT识别符。这是SELECT的查询序列号。
  • select_type:表示SELECT语句的类型。
  • table:表示查询的表。
  • partitions:表示 explain 的一行需要访问哪个表的分区。
  • type:表示表的连接类型。
  • possible_keys:给出了MySQL在搜索数据记录时可选用的各个索引。
  • key:是MySQL实际选用的索引。
  • key_len:给出索引按字节计算的长度,key_len数值越小,表示越快。
  • ref:给出了关联关系中另一个数据表里的数据列名。
  • rows:是MySQL在执行这个查询时预计会从这个数据表里读出的数据行的个数。
  • filtered:表示存储引擎返回的数据过滤后,剩下多少满足查询的记录数量的比例。单位是百分比,100%表示数据没有被过滤。
  • Extra:提供了与关联操作有关的信息。

6.explain你一般关注什么?

重点要关注如下几列:

列名备注
type本次查询表联接类型,从这里可以看到本次查询大概的效率
key最终选择的索引,如果没有索引的话,本次查询效率通常很差
key_len本次查询用于结果过滤的索引实际长度
rows预计需要扫描的记录数,预计需要扫描的记录数越小越好
Extra额外附加信息,主要确认是否出现 Using filesort、Using temporary 这两种情况

其中,type包含以下几种结果,从上之下依次是最差到最好:

类型备注
ALL执行full table scan,这是最差的一种方式
index执行full index scan,并且可以通过索引完成结果扫描并且直接从索引中取的想要的结果数据,也就是可以避免回表,比ALL略好,因为索引文件通常比全部数据要来的小
range利用索引进行范围查询,比index略好
index_subquery子查询中可以用到索引
unique_subquery子查询中可以用到唯一索引,效率比 index_subquery 更高些
index_merge可以利用index merge特性用到多个索引,提高查询效率
ref_or_null表连接类型是ref,但进行扫描的索引列中可能包含NULL值
fulltext全文检索
ref基于索引的等值查询,或者表间等值连接
eq_ref表连接时基于主键或非NULL的唯一索引完成扫描,比ref略好
const基于主键或唯一索引唯一值查询,最多返回一条结果,比eq_ref略好
system查询对象表只有一行数据,这是最好的情况

另外,Extra列需要注意以下的几种情况:

关键字备注
Using filesort将用外部排序而不是按照索引顺序排列结果,数据较少时从内存排序,否则需要在磁盘完成排序,代价非常高,需要添加合适的索引
Using temporary需要创建一个临时表来存储结果,这通常发生在对没有索引的列进行GROUP BY时,或者ORDER BY里的列不都在索引里,需要添加合适的索引
Using index表示MySQL使用覆盖索引避免全表扫描,不需要再到表中进行二次查找数据,这是比较好的结果之一。注意不要和type中的index类型混淆
Using where通常是进行了全表/全索引扫描后再用WHERE子句完成结果过滤,需要添加合适的索引
Impossible WHERE对Where子句判断的结果总是false而不能选择任何数据,例如where 1=0,无需过多关注
Select tables optimized away使用某些聚合函数来访问存在索引的某个字段时,优化器会通过索引直接一次定位到所需要的数据行完成整个查询,例如MIN()\MAX(),这种也是比较好的结果之一

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

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

相关文章

【Linux】网络编程 - Socket套接字/基于UDP的网络通信

目录 一.套接字 1.什么是套接字/Socket套接字 2.套接字的分类 3.Socket套接字的常见API 二.网络字节序 1.什么是网络字节序 2.网络字节序和主机字节序的转换接口 三.IP地址形式上的转换 四.客户端的套接字不由程序员bind 1.为什么客户端套接字不能由程序员bind 2.OS…

【题外话】如何拯救小米11Pro这款工业垃圾

1 背景媳妇用小米11Pro手机,某日不慎摔落,幸好屏幕未碎,然而WiFi却怎样都无法打开,初以为是系统死机,几天依旧故障无法使用。现在的手机没有WiFi功能,就无法刷抖音、看视频,就是鸡肋了。后抽空去…

全栈之路-前端篇 | 第三讲.基础前置知识【前端标准与研发工具】学习笔记

欢迎关注「全栈工程师修炼指南」公众号点击 👇 下方卡片 即可关注我哟!设为「星标⭐」每天带你 基础入门 到 进阶实践 再到 放弃学习!涉及 企业运维、网络安全、应用开发、物联网、人工智能、大数据 学习知识“ 花开堪折直须折,莫待无花空折…

【2.19】算法题2:贪心算法、动态规划、分治

题目:给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组 是数组中的一个连续部分。方法一:贪心算法原理:若当前指针所指元素之前的和小…

学生和老师-课后程序(JAVA基础案例教程-黑马程序员编著-第四章-课后作业)

【案例4-4】学生和老师 【案例介绍】 1.案例描述 在班级中上课时,老师在讲台上讲课,偶有提问,会点名学生回答问题。虽然老师和学生都在讲话,但讲话的具体内容却不相同。本案例要求使用抽象类的知识编写一个程序实现老师上课的情…

Allegro如何快速清除多余的规则设置操作指导

Allegro如何快速清除多余的规则设置操作指导 在用Allegro做PCB设计的时候,会给PCB设置一些规则,在PCB设计完成之后,可能会有一些没有使用到的规则,如下图 Physical规则中的45OHM的规则是多余的 单独某个规则可以直接在规则管理器中删除,如果比较多可以用下面方法批量删除…

真实景观渲染技巧【Three.js】

受到一些很棒的 three.js 演示、与 covid 相关的旅行禁令以及可能在 pinterest 上花太多时间看美丽的旅行照片的启发——我开始看看我是否可以使用 three.js 和r3f在浏览器中渲染一个令人信服的风景场景。 推荐:将 NSDT场景编辑器 加入你的3D开发工具链。 在过去一个…

AnLogicFPGA设计的时序约束及时序收敛

本篇博文讲了三个内容:时序约束基本概念、时序约束命令、时序收敛技巧 时序约束基本概念 时序设计的实质就是满足每一个触发器的建立(setup)时间和保持(hold)时间。 建立时间(Tsu) 触发器的时钟信号沿到来以前&…

零信任-新华三H3C零信任介绍(12)

​目录 ​新华三零信任是什么? 新华三零信任架构特点 新华三零信任架构 新华三零信任架构适用场景 新华三零信任的未来发展展望 新华三零信任是什么? 建立新边界 全面身份化。新华三贯彻“永不信任,始终验证”的原则,通过对…

JavaWeb7-线程状态(生命周期)及转换过程

目录 1.所有线程状态(共6种) ①NEW-新建状态 ②RUNNABLE-运行状态 RUNNABLE(得到时间片运行中状态) READY(已经保存了上下文,但还未得到时间片的就绪状态)。 ③BLOCKED-阻塞状态 ④WAITI…

使用NutUI创建小程序和H5界面

做开发的时间长了,技术都是通用的,创建小程序和H5界面有很多的UI,本章节演示使用NutUI来创建,官网,NutUI - 移动端 Vue3 小程序组件库 1.使用HBuilder X创建一个uni-app的程序,如图所示 2. 安装UniNutUI …

nvm的使用与坑

1、nvm 介绍 Node Version Manager - 符合 POSIX 标准的 bash 脚本,用于管理多个活动的 node.js 版本 官网为 nvm-windows,点击这里进行下载 2、使用场景 比如有几个项目,这些项目的需求都不太一样,导致了这些个项目需要依赖的…

论文投稿指南——中文核心期刊推荐(管理学)

【前言】 🚀 想发论文怎么办?手把手教你论文如何投稿!那么,首先要搞懂投稿目标——论文期刊 🎄 在期刊论文的分布中,存在一种普遍现象:即对于某一特定的学科或专业来说,少数期刊所含…

多彩的声音-课后程序(JAVA基础案例教程-黑马程序员编著-第四章-课后作业)

【案例4-3】多彩的声音 记得 关注,收藏,评论哦,作者将持续更新。。。。 【案例介绍】 案例描述 设计和实现一个Soundable发声接口,该接口具有发声功能,同时还能调节声音大小。 Soundable接口的这些功能将由有3种声音…

【C++的OpenCV】第一课-opencv的介绍和安装(Linux环境下)

第一课-目录一、基本介绍1.1 官网1.2 git源码1.3 介绍二、OpenCV的相关部署工作2.1 Linux平台下部署OpenCV一、基本介绍 1.1 官网 opencv官网 注意:官网为英文版本,可以使用浏览器自带的翻译插件进行翻译,真心不推荐大家去看别人翻译的&am…

vue实现xml在线编辑功能

先看效果 避免误会 这是一个在线编辑器 我们可以在这上面随意的编写xml代码格式 我们修改上面的内容之后 就可以在控制台输出内容 如果这正是您想要的东西 那就可以先创建一个vue项目 我们先引入依赖 npm install brace -S npm install element-ui -S npm install vue-cli…

原型链污染

目录 前置知识 原型对象 prototype和__proto__的区别 原型链概念 原型链的继承 原型 链污染 原型链污染原理 javascript中可能会存在原型链污染的危险函数 原型链污染的实际应用 JavaScript中可以触发弹窗的函数 前置知识 原型对象 在JavaScript中,每个函…

9-静态链表及其有关操作

链表可以用malloc/new和结构体加指针的方式来实现,那种实现方式实现的链表又被称为动态链表。但是我们还可以利用数组的方式来实现一个链表,这种实现方式称为静态链表。 静态单链表 我们知道,一个链表节点主要由两大部分组成:数…

黑马Spring学习笔记(一)——IOC/DI核心概念、入门案例

目录 一、Spring系统架构和学习路线 二、Spring核心概念 2.1 IOC、IOC容器、Bean、DI 2.1.1 IOC(Inversion of Control)控制反转 2.1.2 DI(Dependency Injection)依赖注入 2.2 核心概念小结 三、入门案例 3.1 IOC入门…

【C++入门】引用、内联函数、auto关键字、基于范围的for循环(C++11)、指针空值nullptr(C++11)

文章目录引用引用概念引用特性引用使用场景常引用内联函数宏的优缺点?C有哪些技术替代宏?auto关键字auto不能推导的场景基于范围的for循环(C11)指针空值nullptr(C11)引用 引用概念 引用不是新定义一个变量,而是给已存在变量取了一个别名&…