MYSQL优化方式-附实际操作校验

2024-01-24 17:50

本文主要是介绍MYSQL优化方式-附实际操作校验,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文优化内容主要针对MySQL,有些会进行实际操作进行检验
参考
SQL优化最干货总结(2020最新版)
设计索引的原则是什么?怎么避免索引失效?

总结三点

  • 最大化利用索引
  • 尽可能避免全表扫描
  • 减少无效数据的查询

本文所用例:mainten表
SELECT count(*) FROM or_mainten
在这里插入图片描述
已有索引
在这里插入图片描述

1、避免出现select *

使用select * 取出全部列,会让优化器无法完成索引覆盖扫描这类优化,会影响优化器对执行计划的选择,也会增加网络带宽消耗,更会带来额外的I/O,内存和CPU消耗。
建议:只查询业务需要的字段

2、对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引

注意:只有单单order by 是无法使用到索引的
在这里插入图片描述
在这里插入图片描述

3、尽量避免在字段开头模糊查询,会导致数据库引擎放弃索引进行全表扫描。如下:

SELECT * FROM t WHERE username LIKE '%陈%'
优化方式:尽量在字段后面使用模糊查询。如下:
SELECT * FROM t WHERE username LIKE '陈%'

实际操作测试:
在这里插入图片描述
在这里插入图片描述
如果需求是要在前面使用模糊查询,

  • 使用MySQL内置函数INSTR(str,substr) 来匹配,作用类似于java中的indexOf(),查询字符串出现的角标位置
  • 使用FullText全文索引,用match against 检索
  • 数据量较大的情况,建议引用ElasticSearch、solr,亿级数据量检索速度秒级
  • 当表数据量较少(几千条儿那种),别整花里胡哨的,直接用like ‘%xx%’。

4、应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描

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

5、应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:

下图REAL_MAINTEN_PERSON和status都在索引INDEX_REAL_MAINTEN_PERSON中,但是在or情况下索引失效
在这里插入图片描述

在这里插入图片描述
解决:为or条件中的每个列都建立索引,但是和索引不能建立太多相违背
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

6、应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描,如:

select id from t where num/2=100

应改为:

select id from t where num=100*2

实际操作
选择int字段
在这里插入图片描述
添加索引
在这里插入图片描述

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

7、不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

实际操作
添加索引
在这里插入图片描述
索引失效
在这里插入图片描述
索引正常应用
在这里插入图片描述

8、应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:

select id from t where substring(name,1,3)='abc'
-name以abc开头的id

应改为:

select id from t where name like 'abc%'

实际操作
在这里插入图片描述

9、最左前缀匹配原则

在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
实际操作
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

10、选择区分度大的列作为索引

并不是所有索引对查询都有效,如一表中有字段性别sex,男女几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
原因是当索引列有大量数据重复时,MySQL还有一个查询优化器,查询优化器发现某个值出现在表的数据行中的百分比很高的时候,它一般会忽略索引,进行全表扫描。
惯用的百分比界线是"30%"。(匹配的数据量超过一定限制的时候查询器会放弃使用索引(这也是索引失效的场景之一哦)。

11、索引并不是越多越好

索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。
一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

12、尽量使用数字型字段

若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。
这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了

13、尽可能的使用 varchar 代替 char

因为首先变长字段存储空间小,可以节省存储空间,
其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

14、为频繁查询的字段建立索引

我们在建立索引的时候,要为那些经常作为查询条件的字段建立索引,这样能够提高整个表的查询速度。
但是查询条件一般不是一个字段,所以一般是建立的联合索引比较多。
另外查询条件中一般会有like这样的模糊查询,如果是模糊查询请最好遵守最左前缀查询原则。

15、避免为"大字段"建立索引

这个可以换句话说:就是尽量使用数据量小的字段作为索引。
举个例子来说,假设有两个这样的字段,一个是varchar(5),一个是varchar(200),这种情况下优先选择为varchar(5)的字段建立索引,因为MySQL在维护索引的时候是会将字段值一起维护的,那这样必然会导致索引占用更多的空间,另外在排序的时候需要花费更多的时间去对比。
那假如就要为varchar(100)建立索引呢?那就取部分数据,例如 address 类型为varchar(200),在建立索引的时候可以这么写:

CREATE INDEX tbl_address ON dual(address(20));

16、避免隐式转换

假设字段 age 类型为 int,那我们一般是这么查询的

SELECT * FROM student WHERE age=15
上面这种情况是能使用到索引的,但是如果你这么写
SELECT * FROM student WHERE age='15'
那这种情况是使用不到索引的,也就是age列情的索引是失效的。

MySQL中实际操作发现并不会失效的,未在其它数据库进行验证

1、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:

select id from t where num is null

可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:

select id from t where num=0

在MySQL中实际操作发现并不会放弃使用索引
在这里插入图片描述

2、尽量避免使用in 和not in,会导致引擎走全表扫描。如下:

SELECT * FROM t WHERE id = 1 OR id = 3

实际操作
在这里插入图片描述

这篇关于MYSQL优化方式-附实际操作校验的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/640492

相关文章

MySQL主从同步延迟问题的全面解决方案

《MySQL主从同步延迟问题的全面解决方案》MySQL主从同步延迟是分布式数据库系统中的常见问题,会导致从库读取到过期数据,影响业务一致性,下面我将深入分析延迟原因并提供多层次的解决方案,需要的朋友可... 目录一、同步延迟原因深度分析1.1 主从复制原理回顾1.2 延迟产生的关键环节二、实时监控与诊断方案

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

慢sql提前分析预警和动态sql替换-Mybatis-SQL

《慢sql提前分析预警和动态sql替换-Mybatis-SQL》为防止慢SQL问题而开发的MyBatis组件,该组件能够在开发、测试阶段自动分析SQL语句,并在出现慢SQL问题时通过Ducc配置实现动... 目录背景解决思路开源方案调研设计方案详细设计使用方法1、引入依赖jar包2、配置组件XML3、核心配

MySQL数据库约束深入详解

《MySQL数据库约束深入详解》:本文主要介绍MySQL数据库约束,在MySQL数据库中,约束是用来限制进入表中的数据类型的一种技术,通过使用约束,可以确保数据的准确性、完整性和可靠性,需要的朋友... 目录一、数据库约束的概念二、约束类型三、NOT NULL 非空约束四、DEFAULT 默认值约束五、UN

gradle第三方Jar包依赖统一管理方式

《gradle第三方Jar包依赖统一管理方式》:本文主要介绍gradle第三方Jar包依赖统一管理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景实现1.顶层模块build.gradle添加依赖管理插件2.顶层模块build.gradle添加所有管理依赖包

MySQL 多表连接操作方法(INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN)

《MySQL多表连接操作方法(INNERJOIN、LEFTJOIN、RIGHTJOIN、FULLOUTERJOIN)》多表连接是一种将两个或多个表中的数据组合在一起的SQL操作,通过连接,... 目录一、 什么是多表连接?二、 mysql 支持的连接类型三、 多表连接的语法四、实战示例 数据准备五、连接的性

MySQL中的分组和多表连接详解

《MySQL中的分组和多表连接详解》:本文主要介绍MySQL中的分组和多表连接的相关操作,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录mysql中的分组和多表连接一、MySQL的分组(group javascriptby )二、多表连接(表连接会产生大量的数据垃圾)MySQL中的

Linux之systemV共享内存方式

《Linux之systemV共享内存方式》:本文主要介绍Linux之systemV共享内存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、工作原理二、系统调用接口1、申请共享内存(一)key的获取(二)共享内存的申请2、将共享内存段连接到进程地址空间3、将

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

SpringBoot3.4配置校验新特性的用法详解

《SpringBoot3.4配置校验新特性的用法详解》SpringBoot3.4对配置校验支持进行了全面升级,这篇文章为大家详细介绍了一下它们的具体使用,文中的示例代码讲解详细,感兴趣的小伙伴可以参考... 目录基本用法示例定义配置类配置 application.yml注入使用嵌套对象与集合元素深度校验开发