mysql性能索引调优易混点总结

文章目录

  • 一、 前言
  • 二、explain相关
  • 三、索引优化相关
    • 联合索引
    • 索引下推
    • 排序和分组相关优化
    • 分页优化
    • 表关联优化
    • 嵌套循环连接 Nested-Loop Join(NLJ) 算法
    • in和exsits优化

一、 前言

近几年看了很多和mysql相关的书,文章或视频,但仍然有一些点,看过之后又忘记了,这里做一些笔记来总结一下。

二、explain相关

  1. explain解析后,id列越大执行优先级越高,id相同则从上往下执行,id为NULL最后执行。
  2. select_type列代表的是对应行是简单还是复杂查询。
    1)simple:简单查询。查询不包含子查询和union
    2)primary:复杂查询中最外层的 select
    3)subquery:包含在 select 中的子查询(不在 from 子句中)
    4)derived:包含在 from 子句中的子查询。MySQL会将结果存放在一个临时表中,也称为派生表(derived的英文含义)
  3. 当type是index的时候,代表扫描全索引就能拿到结果,一般是扫描某个二级索引,这种扫描不会从索引树根节点开始快速查找,而是直接对二级索引的叶子节点遍历和扫描,速度还是比较慢的,这种查询一般为使用覆盖索引,二级索引一般比较小,所以这种通常比ALL快一些。
  4. 可以通过key_len来判断使用了是吗索引,char(n)和varchar(n)中n代表的是字符数,而不是字节数。
    varchar(n):如果存汉字则长度是 3n + 2 字节,加的2字节用来存储字符串长度,因为varchar是变长字符串。

三、索引优化相关

联合索引

  1. 联合索引第一个字段就用范围查找不会走索引,mysql内部可能觉得第一个字段就用范围,结果集应该很大,回表效率不高,还不如就全表扫描。当然可以使用forceidex强制走索引,但是效率不一定高。可以用覆盖索引优化。
  2. in和or在表数据量比较大的情况会走索引,在表记录不多的情况下会选择全表扫描。

索引下推

  • **好处:**索引下推主要是为了减少回表次数,并且只能用于二级索引,innodb主键索引保存的是全行数据,索引下推不会减少回表次数。
  • **原理:**比如对于辅助的联合索引(name,age,position),正常情况按照最左前缀原则
    SELECT * FROM employees WHERE name like 'LiLei%' AND age = 22 AND position ='manager'
    这种情况只会走name字段索引,因为根据name字段过滤完,得到的索引行里的age和position是无序的,无法很好的利用索引。
    在MySQL5.6之前的版本,这个查询只能在联合索引里匹配到名字是 ‘LiLei’ 开头的索引,然后拿这些索引对应的主键逐个回表,到主键索引上找出相应的记录,再比对age和position这两个字段的值是否符合。
    MySQL 5.6引入了索引下推优化,可以在索引遍历过程中,对索引中包含的所有字段先做判断,过滤掉不符合条件的记录之后再回表,可以有效的减少回表次数。使用了索引下推优化后,上面那个查询在联合索引里匹配到名字是 ‘LiLei’ 开头的索引之后,同时还会在索引里过滤age和position这两个字段,拿着过滤完剩下的索引对应的主键id再回表查整行数据。

排序和分组相关优化

  1. 在order by和group by中,也能使用到索引,但不会显示在key_len字段中,会在extra中有显示,比如当某个字段用在排序,那么额外字段里没有using filesort。
  2. 对于排序来说,多个相等条件(in),也是范围查询,也会出现using filesort。

分页优化

EXPLAIN select * from employees ORDER BY name limit 90000,5;

  • 对于深度分页,比如limit 10000,10,mysql会查询出前面10010条数据,并舍弃掉10000条数据,只要后面的10条数据这样效率很低。
  • 如果是连续的,可以用 id>10000 limit 5实现。但弊端很大,要保证数据连续,还要保证如果排序了,排序的时候是按照主键排序的。(扫描整个索引并查找到没索引的行,可能要遍历多个索引树)的成本比扫描全表的成本更高,所以优化器放弃使用索引。)
  • 如何优化?
    其实关键是让返回的数据尽可能少,所以可以让排序和分页操作先查出主键,然后根据主键查到对应的记录,SQL改写如下
    select * from employees e inner join (select id from employees order by name limit 90000,5) ed on e.id = ed.id;

这样避免了filesort文件排序,还走了索引。

表关联优化

  • 执行计划中首先执行的是驱动表,后执行的是被驱动表,驱动表一般数量级少。 使用 inner join 时,排在前面的表并不一定就是驱动表。
  • 当使用left join时,左表是驱动表,右表是被驱动表,当使用right join时,右表时驱动表,左表是被驱动表,当使用join时,mysql会选择数据量比较小的表作为驱动表,大表作为被驱动表。

嵌套循环连接 Nested-Loop Join(NLJ) 算法

前提:t2表100行数据,t1表1万行数据。

一次一行循环地从第一张表(称为驱动表)中读取行,在这行数据中取到关联字段,根据关联字段在另一张表(被驱动表)里取出满足条件的行,然后取出两张表的结果合集。

如果被驱动表的关联字段没索引,使用NLJ算法性能会比较低,mysql会选择Block Nested-Loop Join算法。
如果上面使用 Nested-Loop Join,那么扫描行数为 100 * 10000 = 100万次,这个是磁盘扫描。
很显然,用BNL磁盘扫描次数少很多,相比于磁盘扫描,BNL的内存计算会快得多。

从表 t2 中读取一行数据(如果t2表有查询过滤条件的,用先用条件过滤完,再从过滤结果里取出一行数据);
从第 1 步的数据中,取出关联字段 a,到表 t1 中查找;
取出表 t1 中满足条件的行,跟 t2 中获取到的结果合并,作为结果返回给客户端;
重复上面 3 步。

被驱动表的关联字段没索引为什么要选择使用 BNL 算法而不使用 Nested-Loop Join 呢?
用BNL磁盘扫描次数少很多,相比于磁盘扫描,BNL的内存计算会快得多。
因此MySQL对于被驱动表的关联字段没索引的关联查询,一般都会使用 BNL 算法。如果有索引一般选择 NLJ 算法,有索引的情况下 NLJ 算法比 BNL算法性能更高。

in和exsits优化

原则:小表驱动大表,即小的数据集驱动大的数据集(应建立索引)
in:当B表的数据集小于A表的数据集时,in优于exists

select * from A where id in (select id from B)
先执行B,B相当于小表,B表数据越少,执行越快

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

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

相关文章

【吊打面试官系列】Java高并发篇 - 什么是线程组,为什么在 Java 中不推荐使用?

大家好,我是锋哥。今天分享关于 【什么是线程组,为什么在 Java 中不推荐使用?】面试题,希望对大家有帮助; 什么是线程组,为什么在 Java 中不推荐使用? ThreadGroup 类,可以把线程归属…

# 计算机视觉入门

## 概述 计算机视觉(Computer Vision)是人工智能的重要分支领域,它关注于如何使计算机“看”懂图像或视频内容,并从中提取有用信息,对视觉数据进行处理和理解。随着深度学习技术的兴起,计算机视觉领域取得…

排序+去重+二分,LeetCode 2009. 使数组连续的最少操作数

目录 一、题目 1、题目描述 2、接口描述 python3 cpp 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 python3 cpp 一、题目 1、题目描述 给你一个整数数组 nums 。每一次操作中,你可以将 nums 中 任意 一个元素替换成 任意 整数。 如果 …

领鸡蛋游戏养鸡游戏淘宝客源码广告联盟

用户中心 用户信息:显示用户名、头像、鸡蛋数量、足迹等基本信息。我的足迹:展示用户的饲料获取记录明细,包括来源、数量和时间。我的好友:展示邀请的好友列表,支持好友间互动,如串门、偷取/赠送饲料&#…

wait 和 notify

由于线程之间是抢占式执行的, 因此线程之间执行的先后顺序难以预知。但是实际开发中有时候我们可以通过一些 api 让线程主动阻塞,从而控制多个线程之间的执行先后顺序. 完成这些操作就需要用到 wait,notify / notifyAll 注意: wait, notify, notifyAll…

Google Play上架:2024年4月份政策更新改动

4月份政策更新改动 关于恶意软件新增伪装软件新增间谍软件关于移动垃圾软件详细定义关于不当内容暴力极端主义关于设备和网络滥用金融服务关于恶意软件 我们将更新恶意软件政策,阐明伪装软件是一种恶意软件。伪装软件是一种利用多种规避技术向用户提供不一致或虚假功能的应用…

【golang】动态生成微信小程序二维码实战上:golang整合github.com/silenceper/wechat/v2 实现生成 小程序二维码图片

项目背景 在自研的系统,需要实现类似草料二维码的功能 将我们自己的小程序,通过代码生成相想要的小程序二维码 代码已经上传到 Github 需要的朋友可以自取 https://github.com/ctra-wang/wechat-mini-qrcode 一、源生实现 通过源生API实现对小程序二维…

如何让MacOS「终端」走代理

在 MacOS 操作系统中,默认情况下,终端命令行不会通过代理进行网络连接。这导致在应用软件研发过程中,许多需要通过命令行下载安装的软件或依赖包无法成功安装。经常出现Failed to connect to xxx port 443 after 75329 ms: Couldnt connect t…

html写一个登录注册页面

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>注册登录界面Ⅰ</title><link rel"stylesheet" href"https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.mi…

基于SpringBoot+vue的在线商城系统+论文+免费远程调试

基于SpringBootvue的在线商城系统034(含源码 数据库文档免费送&#xff09; 开发系统:Windows10 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springb…

苹果电脑(Mac)怎么清理 itunes 备份?

苹果电脑用户广泛利用 iTunes 应用程序对 iPhone 或 iPad进行定期备份&#xff0c;以确保珍贵的数据安全无虞。然而&#xff0c;随着备份历史的增长&#xff0c;它们会在磁盘上积累大量空间&#xff0c;尤其当您频繁为多台设备备份时&#xff0c;存储资源可能会迅速消耗殆尽。为…

12个深度剖析Python内存管理关键概念

大家好&#xff0c;今天我们要一起探索Python内存管理的神秘世界&#xff0c;就像在侦探小说里解开一个又一个谜团。你知道吗&#xff1f;Python虽然简单易学&#xff0c;但它的内存管理机制却深藏不露&#xff0c;直接影响着程序的性能和效率。让我们一起来揭开这些关键概念的…

第46期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以找…

java工作记录

文章目录 esayExcel导出依赖后端代码controllerservice单元格宽度配置类util 前端代码 若依配置多数据源 esayExcel 导出 依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.4</vers…

基于SpringBoot+Vue+Mysql的图书管理系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

为什么 C/C++ 的库很喜欢缩写?

一、正如很多回答已经提到的&#xff0c;早期的有效标识符长度有限制&#xff0c;所以缩写用得比较多。也主要是在 C 里&#xff08;Unix 的传统&#xff09;。C 里的标识符用缩写的不多。如 C98&#xff08;毕竟比 C89 晚了 9 年么&#xff09;里我们就已经有了很多挺长的名字…

21 条MySQL 开发规范,太详细了,建议收藏!

数据库对象命名规范 1、数据库对象 数据库对象是数据库的组成部分&#xff0c;常见的有以下几种&#xff1a;表&#xff08;Table &#xff09;、索引&#xff08;Index&#xff09;、视图&#xff08;View&#xff09;、图表&#xff08;Diagram&#xff09;、缺省值&#x…

亚马逊电子产品审核?需要提交UL测试报告?

亚马逊要求销售的电子产品&#xff0c;必须经过检测符合标准才可以上架。 要办理亚马逊美国站UL测试报告&#xff0c;你需要联系国内的第三方检测机构&#xff0c;当然必须是由符合ISO17025/ILAC ISO 17025标准的实验室出具的合格报告&#xff0c;ISO 17025标准是国际上广泛认…

使用flex布局写6种骰子

使用flex布局写6种骰子&#x1f3b2; 效果图 概述说明 不使用position定位&#xff0c;完全靠flex进行分配位置。 在线查看 点击查看 完整代码 <template><div class"content"><ul class"list"><li class"item" v-fo…

视频图像的两种表示方式YUV与RGB(1)

了解过计算机图形图像学的该知道&#xff0c;可用RGB和YUV两种方式表示图像像素&#xff0c;视频由一帧一帧的图像组成&#xff0c;每一张图片是一个一个的像素点组成&#xff0c;既然有两种表示像素的方法&#xff0c;那就一起解一下两种表示方式的异同及优缺点。 RGB像素 这…