【MySQL】SQL 优化

MySQL - SQL 优化

1. 在 MySQL 中,如何定位慢查询?

1.1 发现慢查询

现象:页面加载过慢、接口压力测试响应时间过长(超过 1s)

可能出现慢查询的场景:

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

1.2 通过现象定位到问题是出在 MySQL 的慢查询(查看慢日志法)

找到配置文件:

Windows:my.ini

在这里插入图片描述

Linux:/etc/my.cnf

在这里插入图片描述

添加或修改两个属性:

  1. slow_query_log=1(1 为 true,开启慢日志)
  2. long_query_time=2(单位为秒,超过 2 秒的将记录在慢日志)

选择性添加或修改,slow_query_log_file 属性,慢日志名

  • Linux 在/var/lib/mysql/localhost-slow.log
  • Windows 见配置文件默认值

重启 MySQL:

  • Windows

    • net stop MySQL
      
    • net start MySQL
      
  • Linux

    • sudo systemctl stop mysql
      
    • sudo systemctl start mysql
      

发现问题,找到对应的慢日志,定位到问题是出在 MySQL 的慢查询:

在这里插入图片描述

1.3 回答问题

  1. 介绍一下当时产生问题的场景(我们当时的一个接口测试的时候非常的慢,压力测试的结果大概 5 秒钟);
  2. 而我们在调试阶段,开启了 MySQL 的慢日志记录,我们设置的值为 2 秒,一旦 sql 执行超过 2 秒就会记录在慢日志中,我们发现问题后查询了 MySQL 的慢日志,最终定位到问题是出在 MySQL 的慢查询;

2. 那这个 SQL 语句执行很慢,是如何分析的呢?

可以采用 MySQL 自带的分析工具 explain

  • 通过 key 和 key_len 查询是否命中索引,也可以判断索引本身存在是否失效的情况;
  • 通过 type 字段查看 sql 是否有进一步的优化空间,是否村咋全索引扫描或者全盘扫描;
  • 通过 Extra 建议判断是否出现了回表的情况,如果出现了,可以尝试添加索引或者修改返回字段来修复;

在这里插入图片描述

  • possible_key 当前 sql 可能会使用到的索引

  • key 当前 sql 实际命中的索引

  • key_len 索引占用的大小

  • Extra 额外的优化建议

    在这里插入图片描述

  • type 这条 sql 的连接类型,性能由好到差:NULL、system、const、eq_ref、ref、range、index、all

    • NULL:没有使用到表
    • system:查询 MySQL 系统内置的表
    • const:根据主键索引查询
    • eq_ref:主键索引查询或者唯一索引查询
    • ref:索引查询
    • range:分为查询
    • index:索引树(全索引)扫描
    • all:全盘扫描

3. 了解过索引吗?(什么是索引)

3.1 索引是什么

索引(index)是帮助 MySQL 高效获取 数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构**(B+ 树)**,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。

3.2 什么是 B+ 树

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3.3 回答

了解过索引吗?

  • 索引(index)是帮助 MySQL 高效获取数据的有序的数据结构;
  • 提高数据检索的效率,降低数据库的 IO 成本,因为不需要全表扫描;
  • 通过索引列对数据进行排序,降低数据排序的成本,降低了 CPU 的消耗;

索引列:以表中哪个列来创建索引;

索引的底层数据结构了解过吗?

InnoDB是MySQL数据库管理系统中的一种事务性存储引擎。

MySQL 的 InnoDB 引擎采用的 B+ 树的数据结构来作为索引的存储结构;

  • MySQL 的索引的底层数据结构是 B+ 树;
  • 阶数更多,路径更短;磁盘读写代价低,非叶子节点只存储指针,叶子节点存储数据;
  • B+ 树便于扫库和区间的查询,叶子节点是一个双向链表;

4. 什么是聚簇索引,什么是非聚簇索引?

4.1 什么是聚集索引,什么是二级索引(非聚集索引)?

在这里插入图片描述

在这里插入图片描述

如果没有主键,则会使用隐藏字段:DB_ROW_ID,隐藏主键

4.2 什么是回表查询?

了解什么是聚集索引,什么是二级索引(非聚集索引)后,再进行理解:

在这里插入图片描述

如果没有主键,则会使用隐藏字段:DB_ROW_ID,隐藏主键进行回表查询(如果不给隐藏主键创建索引,那么回表查询是没有走索引的,效率低下)

4.3 回答

  • 聚簇索引(聚集索引):数据存放到索引中,B+ 树的叶子节点保存了整行数据,有且只有一个;
  • 非聚簇索引(二级索引,非聚集索引):数据不全部存放到索引中,B+ 树的叶子节点保存了索引列以及对应的主键,可以有多个;
  • 通过二级索引找到对应的主键值,再到聚集索引中查找整行数据,这个过程就是回表;(如果没有聚集索引,回表查询就不是通过索引查询了,而是全表查询,非常低性能)

5. 知道什么叫覆盖索引吗?

覆盖索引就是查询使用了索引,并且需要返回的列在该索引中已经全部覆盖到了;

在这里插入图片描述

  • 聚集索引一定是,二级索引不需要回表查询也是;

回答:

  • 聚集索引指的是查询使用了索引,返回的列,在索引中全部都能找到;
    • 使用 id 查询,直接走聚集索引查询,一次索引扫描,直接返回全部数据,性能高;
    • 如果所需列在索引中不存在,就会触发回表查询,所以尽量避免使用 select *

6. MySQL 超大分页怎么处理?

在数据量比较大的时候,如果进行 limit 分页查询,在查询的时候,越往后,分页查询效率越低。

6.1 超大分页场景

例如:

select * from user order by nickname limit 0, 10;
select * from user order by nickname limit 9000000, 10;

上面那个 0 毫秒不到,而下面那个甚至可以达到 10 秒以上!

因为,在执行的时候,需要加载 9000010 条记录(每条都是 raw),再选取 9000000 - 9000010 的记录,其他记录丢弃,查询排序的非常大。

而 nickname 在这里不是覆盖索引,所以加载 9000010 条记录时,性能很低。

  • order by 子句使用索引需要:
    1. order by 子句中的字段必须创建了索引,索引查询的字段覆盖需要查询的字段;
    2. order by 子句中的字段要符合最左前缀法则(对于复合索引);
  • 像这种非覆盖索引,回表的性能还不如全表查询呢,所以不走索引在这里是好事;

6.2 超大分页 SQL优化

但是我们知道这条 sql 中是覆盖索引:

select id from user ordery by nickname limit 9000000, 10;

那么我们再拿这 10 个 id 去表中查询即可。

因此 sql 可以优化成这样(覆盖索引 + 子查询):

select * fromuser u, (select id from user order by nickname limit 9000000, 10) a
where u.id = a.id;

6.3 回答

  • 问题在于在数据量比较大时,limit 分页查询,需要对数据进行排序,效率低。

  • 可以用到索引(有序性)查询,而如果不是覆盖索引,那么可以用覆盖索引 + 子查询进行优化!

7. 索引创建的原则有哪些?

先陈述自己实际开发中怎么用索引的,用了什么索引,如主键索引、唯一索引、复合索引…

再说原则:

  1. 数据量较大,且查询比较频繁的表;(10w+ 就可以创建索引增加用户体验了)
  2. 常常作为查询条件、排序操作、分组操作的字段;
  3. 尽量使用联合索引(多列索引),减少单列索引,这样可以让查询更可能是覆盖索引;
  4. 要控制索引的数量,并不是越多越好,增删改都是需要维护的;
  5. 字段内容区分度高,尽量建立唯一索引,区分度越高性能越好;
  6. 字符串类型字段,内容较长,可以使用前缀索引;
  7. 如果索引列不能存储 NULL 值,在创建表的时候使用 NOT NULL 约束,这有利于让优化器选择哪个索引进行更有效的查询;

8. 什么情况下索引会失效?

8.1 复合索引

在这里插入图片描述

顺序见 Seq_in_index,即 name、status、address

8.2 违反最左前缀法则

SQL 的查询条件 / 排序 / 分组从索引的最左前列开始,才会走索引:

在这里插入图片描述

正向例子:

在这里插入图片描述

反向例子:

在这里插入图片描述

跳过某一列,则只有部分最左前缀索引生效:

在这里插入图片描述

8.3 范围查询右边的列,不能使用索引

在这里插入图片描述

下面那个,name 和 status 走索引,status 右边的字段 address 没用到索引。

8.4 不要再索引列上进行运算操作,索引会失效

在这里插入图片描述

8.5 字符串不加单引号,造成索引失效

在这里插入图片描述

复杂行为往往导致索引失效~

8.6 模糊查询有可能会导致索引失效

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

在这里插入图片描述

8.7 回答

同理,先陈述自己的遭遇,如某个场景创建了索引,性能还是很慢,explain 去查看 sql 语句的执行计划,发现索引失效了。

对于复合索引:

  1. 违反最左前缀法则;
  2. 范围查询右边的列;
  3. 在索引列上进行运算操作;
  4. 字符串不加单引号,导致 MySQL 优化器进行类型转化;
  5. 头部模糊查询;

通常情况下,可以使用 explain 查看 sql 的执行计划来判断索引是否失效。

9. 谈一谈你对 SQL 优化的经验

从三个方面:

  1. 表的设计优化
  2. 索引优化(参考优化创建原则和索引失效)
  3. SQL 语句优化

9.1 表的设计优化(参考阿里开发手册《嵩山版》)

  1. 比如设置合适的数值(tinyint、int、bigint)要根据实际情况选择;
  2. 比如设置合适的字符串类型(char,varchar)char定长效率高,varchar可变长度,效率稍低;

9.2 SQL 语句的优化

  1. select 语句务必指明字段的名称(避免使用 select *);
  2. SQL 语句要避免造成索引失效的写法;
  3. 尽量用 union all 代替 union,union 会多一次过滤,效率低(union 会将重复的过滤掉,如果知道没有重复的就可以用 union all)

在这里插入图片描述

这个就不能用 union all,并不是存在绝对地去优化,而是看情况决定~

  1. 避免在 where 子句对字段进行表达式/函数操作;

  2. join 优化,能用 inner join 就不用 left join 或者 right join,如果必须使用,一定要以小表为驱动;

    • 小表:数据量较小的表,大表:数据量较大的表,

    • 这样的好处就是以小表连接大表,连接次数较小,on 子句查询的次数较小,并且由于是查询大表,所以如果是有索引,索引效果更明显!

    • 内连接会对两个表进行优化,优先把小表放外边,把大表放里面;

    • left join 或者 right join 则不会重新调整顺序;

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

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

相关文章

错误笔记:Anaconda 错误(闪退、无法安装等) + Pycharm 错误(无法启动)+ python 报错

Anaconda 错误 1、导航器启动中发生-- 闪退 方法一: Windows下: 1)使用管理员运行:conda prompt 2)执行命令 conda update anaconda-navigator 方法二: 重置Anaconda配置:anaconda-navigator…

C语言第三十四弹---动态内存管理(下)

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】 动态内存管理 1、动态内存经典笔试题分析 1.1、题目1 1.2、题目2 1.3、题目3 1.4、题目4 2、柔性数组 2.1、柔性数组的特点 2.2、柔性数组的使用 2.3、…

5.STL源码解析-算法、仿函数、适配器

算法 STL算法总览 仿函数与适配器 C标准模板库(STL)是C程序员的得力工具,提供了许多强大而高效的数据结构和算法。在STL中,仿函数(Functor)和适配器(Adapter)是两个重要的概念…

【C++精简版回顾】17.io流,流中提供的函数

1.流含义 2.流类 3.流对象 4.流对象的函数 举例&#xff1a; 要求&#xff1a;数据结构中经常需要对齐输出数据&#xff0c;应该怎么做&#xff1f; 1.头文件 #include<iomanip> 2.创建表格头 cout << setiosflags(ios::left) << setw(8) << "姓名…

BUGKU 网站被黑

打开环境&#xff0c;什么都没发现&#xff0c;使用蚁剑扫描一下&#xff0c;发现shell.php&#xff0c;打开 使用BP抓包&#xff0c;进行爆破 得到密码&#xff1a;hack 进去得到flag

每日一类:QLabel深入解析

QLabel是Qt中用于显示文本或图像的控件&#xff0c;属于Qt Widgets模块。它是展示静态内容的理想选择&#xff0c;支持富文本格式&#xff0c;使得文本可以包含不同的字体、颜色和链接。QLabel也可以用来显示图像&#xff0c;包括动态图像。此外&#xff0c;它还支持文本和图像…

【考研数学】汤家凤1800题什么水平?

我觉得汤家凤基础武忠祥强化这个组合非常的不错 汤家凤老师的讲课风格 汤家凤老师的基础课程是大家公认的讲的详细&#xff0c;并且非常照顾基础不好的学生&#xff0c;会把基础知识点掰开揉碎的讲给大家听&#xff0c;在上课过程中&#xff0c;还会把知识点写在A4纸上&#…

R750 install AMD MI210GPU

一、 查看服务器GPU卡信息 可以首先在服务器上check 当前GPU的详细信息是否匹配 二、安装 Ubuntu22.04操作系统 服务器CHECK 安装的AMD GPU 是否被系统识别 #lspci | grep AMD 查看GPU信息 可以看到已经识别成功 三、安装AMD GPU驱动 https://rocm.docs.amd.com/projec…

智能驾驶规划控制理论学习05-车辆运动学规划案例分析

目录 案例一——Hybrid A*&#xff08;基于正向运动学&#xff09; 1、基本思想 2、 实现流程 3、启发函数设计 4、分析扩张&#xff08;Analytic Expansions&#xff09; 5、分级规划&#xff08;Hierarchical planning&#xff09; 案例二——State Lattice Planning&…

子矩阵的和 刷题笔记 {二维前缀和}

首先我们的目标是让 s[i][j]表示为其左方和上方形成的矩阵所有元素的和 加上s[i-1][j]和s[i][j-1]后 s[i-1][j-1]部分重复了所以减去 最后加上a[i][j]即可完成目标 s[i][j]s[i-1][j]s[i][j-1]-s[i-1][j-1]a[i][j]; 然后看题目要求 要求x1,y1,x2,y2围成的小正方形内的元素和…

C/C++工程师面试题(数据库篇)

索引的优缺点 索引是一种支持快速查找特定行的数据结构&#xff0c;如果没有索引&#xff0c;就需要遍历整个表进行查找。用于提高数据检索的速度和效率。 好处&#xff1a; 提高检索速度&#xff1a; 索引可以加快数据的检索速度&#xff0c;因为它们允许数据库系统直接定位到…

Revit-二开之立面视图创建FilledRegion-(3)

在上一篇博客中介绍了FilledRegion的创建方法,这种方法通常只在平面视图中适用,在三维视图中也是无法创建的(目前研究的是这样的,如果有其他方法,请赐教)。 本片文章介绍一个下在立面视图中创建FilledRegion的方法,主要操作是在立面视图中拾取一个点,然后以该点为原点,…

YOLOv5 项目:推理代码和参数详细介绍(detect)

1、前言 本章将介绍yolov5项目的推理函数&#xff0c;关于yolov5的下载和配置环境&#xff0c;参考上一篇文章&#xff1a; YOLOv5 项目&#xff1a;环境配置-CSDN博客 pycharm 中打开的推理模块如红框中所示 pycharm将conda新建的虚拟环境导入&#xff0c;参考 &#xff1a;…

简单实现Transformer的自注意力

简单实现Transformer的自注意力 关注{晓理紫|小李子}&#xff0c;获取技术推送信息&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持&#xff01;&#xff01; 如果你感觉对你有所帮助&#xff0c;请关注我。 源码获取&#xff1a;VX关注并回复chatg…

二叉树的右视图,力扣

目录 题目&#xff1a; 我们直接看题解吧&#xff1a; 快速理解解题思路小建议&#xff1a; 审题目事例提示&#xff1a; 解题方法&#xff1a; 解题分析&#xff1a; 解题思路&#xff1a; 代码实现(DFS)&#xff1a; 代码1&#xff1a; 补充说明&#xff1a; 代码2&#xff1…

AI:148-开发一种智能语音助手,能够理解和执行复杂任务

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带关键代码,详细讲解供大家学习,希望…

[技巧]Arcgis之图斑四至点批量计算

前言 上一篇介绍了arcgis之图斑四至范围计算&#xff0c;这里介绍的图斑四至点的计算及获取&#xff0c;两者之间还是有差异的。 [技巧]Arcgis之图斑四至范围计算 这里说的四至点指的是图斑最东、最西、最南、最北的四个地理位置点坐标&#xff0c;如下图&#xff1a; 四至点…

STM32进阶笔记——复位、时钟与滴答定时器

本专栏争取每周三更新直到更新完成&#xff0c;期待大家的订阅关注&#xff0c;欢迎互相学习交流。 目录 一、复位1.1 软件复位1.2 低功耗管理复位 二、时钟2.1 系统时钟(SYSCLK)选择2.2 系统时钟初始化 三、滴答定时器&#xff08;Systick&#xff09;3.1 SysTick部分寄存器3.…

部署bpmn项目实现activiti流程图的在线绘制

本教程基于centos7.6环境中完成 github开源项目: https://github.com/Yiuman/bpmn-vue-activiti软件&#xff1a;git、docker 1. 下载源代码 git clone https://github.com/Yiuman/bpmn-vue-activiti.git2. 修改Dockerfile文件 声明基础镜像&#xff0c;将项目打包&#xff…

EasyRecovery数据恢复软件有什么优势呢?

EasyRecovery数据恢复软件具有以下优势&#xff1a; 强大的恢复能力&#xff1a;EasyRecovery采用先进的扫描和恢复技术&#xff0c;能够深度扫描存储设备&#xff0c;寻找并恢复因各种原因丢失的数据。无论是误删除、格式化、分区损坏还是病毒感染&#xff0c;它都能提供有效…