MySQL索引怎么优化

索引优化无非就是两点:

  • 把SQL的写法进行优化,对于无法应用索引,或导致出现大数据量检索的语句,改为精准匹配的语句。
  • 对于合适的字段上建立索引,确保经常作为查询条件的字段,可以命中索引去检索数据。

连接查询时尽量不关联太多表

关联太多会导致执行效率变慢

多表查询时一定要以大驱小

用小的数据集去驱动大的数据集,就是先查小表,用小表的结果去大表中检索数据,MySQL的优化器有驱动表的优化,执行多表联查MySQL的关联算法为Nest Loop Join,该算法会依照驱动表的结果集作为循环基础数据,然后通过该结果集中一条条数据,作为过滤条件去下一个表中查询数据,最后合并结果得到最终数据集。

  • 指定了连接条件,满足查询条件的小数据表作为驱动表。
  • 未指定连接条件,数据总行数少的表作为驱动表。

通常使用in做子查询时,都要确保in的条件位于所有条件的最后面,这样能够在最大程度上减小多表查询的数据匹配量,在下一道工序开始前尽量缩小数据量,为下一道工序尽可能提供更加精准的数据。

不要使用like左模糊和全模糊查询

like关键字以 % 开头会导致索引失效,千万要避免 %xxx、%xxx% 这两种情况出现。

查询时不要对字段做空值判断

会导致索引失效,想为空的字段,可以设计一个0、" "这类空字符代替,一方面要查询空值时可通过查询空字符的方式走索引检索,同时也能避免MyBatis注入对象属性时触发空指针异常。

不要在条件查询 = 前对字段做任何运算

使用函数也不可以,优化器生成执行计划时,发现 = 前涉及逻辑运算就不会继续往下走了。

!=、!<>、not in、not like、or...要慎用

也可能会导致索引失效,可以使用其他语法代替,比如or使用union all代替。

select user_name from zz_users where user_id=1 or user_id=2;
-- 可以替换成:
select user_name from zz_users where user_id=1
union all
select user_name from zz_users where user_id=2;

必要情况可以强制指定索引

优化器面对复杂 SQL 时没有那么智能,有时选择的索引并不是做好的,对索引结构足够熟悉的情况下,可以通过force index指定索引。

select * from zz_users force index(unite_index) where user_name = "熊猫";

避免频繁创建、销毁临时表

临时表是一种数据缓存,对于一些常用的查询结果可以为其建立临时表,后续要查询时可以直接基于临时表来获取数据,MySQL默认会在内存中开辟一块临时表数据的存放空间,走临时表查询数据是直接基于内存的,速度会比走磁盘检索快上很多倍。注意:只有对于经常查询的数据才对其建立临时表,不要盲目的去无限制创建,否则频繁的创建、销毁会对MySQL造成不小的负担。

尽量将大事务拆分为小事务执行

一个事务在执行时,如果包含了写操作,会先获取锁再执行,直到事务结束后MySQL才会释放锁。一个事务比较大时,导致一部分数据锁定周期长,高并发情况下会有大量事务阻塞,最终拖垮整个MySQL系统。

  • show status like 'innodb_log_waits';查看是否有大事务由于redo_log_buffer不足,而在等待写入日志。

大事务也会导致日志写入时出现阻塞,这种情况下会强制触发刷盘机制,大事务的日志需要阻塞到有足够的空间时,才能继续写入日志到缓冲区,这也可能会引起线上出现阻塞。

从业务设计层面减少大量数据返回的情况

一次性返回的数据量过于巨大时,就会引起网络阻塞、内存占用过高、资源开销过大的各类问题出现,如果项目中存在这类业务,一定要拆分掉,比如分批返回给客户端。每次基于上次返回数据的界限,再一次读取一批数据返回给客户端,也就是经典的分页场景,通过分页的思想能够提升单次查询的速度,以及避免大数据量带来的一系列后患问题。

避免深分页的情况出现

select xx,xx,xx from yyy limit 100000,10; 

查询第1w 页数据,一共查询10w 条数据,然后丢弃前10w 条数据返回最后10条数据。

  • 解决方案:

查询的结果集存在递增且连续的字段,可以基于有序字段做一步筛选在获取分页数据。这种情况会先按where条件筛选数据后,再获取前10条数据返回。也可通过between做优化。

-- 第一页
select xx,xx,xx from yyy where 有序字段 >= 1 limit 10; 
-- 第二页
select xx,xx,xx from yyy where 有序字段 >= 11 limit 10; 
-- 第N页.....-- 第10000页
select xx,xx,xx from yyy where 有序字段 >= 100001 limit 10; 
-- 舍弃了limit关键字来实现分页,但这种方式仅适合于基于递增且连续字段分页。
select xx,xx,xx from yyy where 有序字段 between 1000000 and 1000010; 

搜素分页的情况下是无序的,数据可以位于表中的任意行,就算存在有序字段也不会连续。就只能通过在业务上限制深分页的情况。以百度为例,显示大约搜索到了一亿条数据,往后拉就会发现,最大只能显示76页,然后会提示“限于网页篇幅,部分结果未予显示”。这种思想仅局限于业务允许的情况下,以搜索为例,一般用户最多看前面30页,如果还未找到他需要的内容,基本上就会换个更精准的关键词重新搜索。

如果业务必须要求展现所有分页数据,此时又不存在递增的连续字段,要么选择之前哪种很慢的分页方式,要么就直接抛弃所有!每次随机十条数据出来给用户,如果不想重复的话,每次新的分页时,再对随机过的数据加个标识即可。

SQL务必写完整,不要使用缩写

这种隐式的写法在MySQL底层会做一次转换,为完整的写法。考虑极致的优化,将SQL写成完整的语法。

-- 为字段取别名的简单写法
select user_name "姓名" from zz_users;
-- 为字段取别名的完整写法
select user_name as "姓名" from zz_users;-- 内连表查询的简单写法
select * from 表1,表2... where 表1.字段 = 表2.字段 ...; 
-- 内连表查询的完整写法
select * from 表1 别名1 inner join 表2 别名2 on 别名1.字段 = 别名2.字段;

基于联合索引查询时确保字段的顺序性

基于建立的联合索引查询数据,就必须要按照索引字段的顺序去查询数据,否则可能导致不能完全利用联合索引,要遵循索引最左前缀原则。

客户端的一些操作可批量化完成

xxDao.insertBatch(xxObjs);/*** xxDao.insertBatch(xxObjs)对应的SQL如下:* insert into tb_xxx values(......),(......),(......),(......),.....;
**/

会组合成一条SQL发送给MySQL执行,能够在很大程度上节省网络资源的开销,提升批量操作的执行效率。同样适用于修改场景,如果一个业务会出现批量修改的情况时,也切记不要用for循环来调用update语句对应的接口,而是应该再写一个update/replace语句的批量修改接口。

明确仅返回一条数据的语句可以使用limit 1

select * from zz_users where user_name = "竹子";
select * from zz_users where user_name = "竹子" limit 1;

后者大多数情况下会比前者好,加上limit 1关键字后,当程序匹配到一条数据时就会停止扫描,不加的情况下会将所有数据都扫描一次。一般情况下,如果确定了只需要查询一条数据,就可以加上limit 1提升性能。

但在一些极端情况下,性能可能相差不大,比如要查询的数据位于表/索引文件的最后面,那么依旧会全部扫描一次。还有一种情况是基于主键/唯一索引字段查询数据时,这些字段值本身具备唯一性,MySQL在执行时,当匹配到第一个值时就会自动停止扫描,因此上述这个方案只适用于普通索引字段、或表中的普通字段。

参考文档

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

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

相关文章

同步时钟:北斗/GPS卫星、电信基站、NTP以太网校时方式的区别

同步时钟是保证各设备时间统一的重要装置&#xff0c;广泛应用于电力、通信、金融、学校、医院、地铁等多个领域。目前&#xff0c;常用的同步时钟方式包括&#xff1a;北斗/GPS卫星、电信基站、NTP以太网等。 下面跟着小编来看一下这些校时方式及他们的区别吧。 1. 北斗/GP…

另一种方式编译ZYNQ镜像

文章目录 1.创建Petalinux工程&#xff0c;生成BOOT.BIN创建Petalinux工程配置Petalinux工程生成BOOT.BIN 2.生成设备树文件3.编译kernel添加设备树文件defconfig配置menuconfig 配置编译内核源码编译设备树 4.编译rootfs5.启动开发板制作SD启动卡拷贝镜像到FAT分区将根文件系统…

Windows 安装docker详细步骤说明

文章目录 1. 检查系统要求2. 启用硬件虚拟化3. 启用Hyper-V和容器功能4. 下载并安装Docker Desktop5. 配置Docker Desktop6. 安装WSL 27. 验证Docker安装8. 常见问题排查9. 重点说明参考资源 在Windows上安装Docker的详细步骤如下&#xff1a; 1. 检查系统要求 确保您的Window…

数据库断言-数据库连接池

原因&#xff1a;现在的代码是单线程&#xff0c;如果遇到大并发的话就会崩溃&#xff0c;数据库查询就查不过来 措施&#xff1a;需要建立数据库连接池&#xff0c;可以设置连接池的数量 什么是大并发&#xff1a;很多客户端在idea写的程序和数据库建立连接 步骤&#xff1…

SAP Build 3-调用SAP BAPI和调用S4HC API

1. 调用SAP BAPI 1.1 前提 项目已创建 SAP环境登录正常 1.2 引入BAPI SDK 商店中下载BAPI SDK Process中导入BAPI SDK 1.3 新建action group 新建action group时&#xff0c;会要求填写SAP登录信息&#xff0c;根据连接类型分为SSO&#xff0c;Basic和Custom 如果选择SS…

SAP配置发布WebService接口并调用(超级详细)

文章目录 前言一、案例介绍/笔者需求二、WebService是什么&#xff1f; a.传输协议 b.数据协议 c.WSDL d.UDDI 三、WebService 和 WebApi 的区别以及优缺点 a.主要区别 b.优缺点 四、SAP如何发布一个webser…

C++编程(六)运算符重载

文章目录 一、概念1. 左值和右值2. 运算符重载3. 可以实现重载的运算符和不可以实现重载的运算符 二、双目运算符&#xff08;一&#xff09;说明&#xff08;二&#xff09;实现1. 注意点2. 算术运算符成员函数版本全局函数版本 3. 关系运算符成员函数版本全局函数版本 三、赋…

技术反诈指南丨央视报了!基于“AI换脸”的新型电信网络诈骗猖獗

目录 利用“AI换脸”技术的诈骗 技术上防范新型电信网络诈骗 内蒙古鄂尔多斯市居民李女士近日遭遇了一起新型电信网络诈骗案。诈骗团伙利用“AI换脸”技术&#xff0c;合成了与李女士老同学相似的视频通话&#xff0c;以此作为诈骗的关键手段&#xff0c;成功骗取李女士信任。 …

【linux】使用vnc连接远程桌面,需要安装tigervnc,并在服务端期待,然后在客户端使用tigervnc-viewer进行连接即可

vnc 远程设置方法 需要服务端安装软件&#xff1a; sudo apt install -y tigervnc-standalone-server# 先配置密码使用&#xff1a; tightvncpasswd启动服务&#xff0c;禁用本机 vncserver -localhost no -geometry 1924x1080 :1客户端安装软件&#xff1a; sudo apt insta…

1974. 使用特殊打字机键入单词的最少时间

关键点&#xff1a; 无论数组的开头第一位是什么&#xff0c;总是从a开始的&#xff0c;从第一个字母向后走的时候有顺时针和逆时针&#xff0c;取最小值当从第一个字母开始走的时候&#xff0c;用当前位置替换a的作用 class Solution:def minTimeToType(self, word: str) -&g…

实现资产优化管理:智慧校园资产分类功能解析

在构建智慧校园的过程中&#xff0c;细致入微的资产管理是确保教育资源高效运作的关键一环&#xff0c;而资产分类功能则扮演着举足轻重的角色。系统通过精心设计的分类体系&#xff0c;将校园内的各类资产&#xff0c;从昂贵的教学设备到日常使用的办公物资&#xff0c;乃至无…

嵌入式linux系统中动态链接库实现详解

大家好,linux系统中动态库是如何实现相互链接的?今天简单聊聊动态链接库的实现原理。 假设有这样两段代码,第一段代码定义了一个全量变量a以及函数foo,函数foo中引用了下一段代码中定义的全局变量b。 第二段代码定义了全局变量b以及main函数,同时在main函数中调用了第一个…

​Chrome插件:React Developer Tools为React开发调试而生

React Developer Tools 是什么? 它是允许在Chrome和Firefox开发者工具中检查React组件层次结构的扩展插件。 插件源码下载 源码下载地址:GitHub - facebook/react-devtools at v3 下载完成以后执行红框中的代码,下载react-devtools 源码,源码如下图所示: 插件打包 当前n…

表单外链,支持查看方式设置

06/19 主要更新模块概览 外链设置 跳转缩放 打印调整 数据校验 01 表单管理 1.1 【表单外链】-填写外链新增查看方式设置 说明&#xff1a; 原表单填写外链&#xff0c;填写字段权限和查看权限统一字段设置&#xff0c;用户在填写时看到数据与查看数据一致…

Qt 使用代码布局,而不使用UI布局

一、工程的建立&#xff1a; 1、打开Qt Creator&#xff0c;文件&#xff0c;新建文件或项目 2、选择Application&#xff0c;Qt Widgets Application 3、写入名称&#xff0c;选择qmake 4、选择基类Base class&#xff0c;去除Generate form 务必选择QWidget&#xff0c;若…

交友系统定制版源码| 相亲交友小程序源码全开源可二开_打造独特的社交交友系统

交友系统源码的实现涉及到多个方面&#xff0c;包括前端页面设计、后端逻辑处理、数据库设计以及用户交互等。以下是一个简单的交友系统源码实现的基本框架和关键步骤: 1.数据库设计:用户表:存储用户基本信息&#xff0c;如用户ID、用户名、密码、头像、性别、年龄、地理位置等…

『手撕Vue-CLI』 添加自定义指令

添加 create 指令 在 vue-cli 中&#xff0c;create 指令是用来创建一个新的项目的&#xff0c;我实现的 nue --help 的帮助信息中只有 --version&#xff0c;--help 这两个指令&#xff0c;所以当用户使用我的 nue-cli 时&#xff0c;并不知道有 create 这个指令&#xff0c;所…

【MySQL】事务实现原理

事务 事务是将一组SQL语句打包成一个整体&#xff0c;在这组SQL的执行过程中&#xff0c;要么全部成功&#xff0c;要么全部失败。这组SQL语句可以是一条也可以是多条。 如果转账成功&#xff0c;应该满足以下要求&#xff1a; 张三的账户余额减少100&#xff0c;变成900&…

Vatee万腾平台:引领行业变革,创新未来

在当今这个快速变化的时代&#xff0c;科技的力量正在以前所未有的速度推动着行业的变革。Vatee万腾平台&#xff0c;以其独特的视角和前瞻性的布局&#xff0c;正引领着行业变革的浪潮&#xff0c;创新着未来的发展方向。 Vatee万腾平台是一家专注于科技研发和创新应用的领军企…

安装PyTorch详细过程(个人过程仅供参考)

1.安装anaconda 2.创建一个虚拟环境 以上步骤默认已经完毕&#xff0c;毕竟只是记录pytorch的安装过程 3.查看个人电脑CUDA版本 winr 输入cmd 回车 输入指令 nvidia-smi 右上角为该电脑所支持的最高CUDA版本 输入命令 nvcc -V 图中即为该电脑所安装的CUDA版本 记住该版…