Mysql进阶-索引篇(下)

 SQL性能分析

SQL执行频率

MySQL 客户端连接成功后,通过 show [session|global] status 命令可以提供服务器状态信息。通过如下指令,可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次,通过sql语句的访问频次,我们可以判断到当前数据库到底是以查询为主,还是以增删改为主,从而为数据库优化提供参考依据。 如果是以增删改为主,我们可以考虑不对其进行索引的优化。 如果是以查询为主,那么就要考虑对数据库的索引进行优化了。

0c62ffe6b8c54f18a43282996117fd77.png

慢查询日志 

如果当前数据库是以查询为主,我们可以通过慢查询日志来查看耗时较长的查询,慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有 SQL语句的日志。MySQL的慢查询日志默认没有开启,我们可以查看一下系统变量 slow_query_log。

 慢查询日志默认是关闭的

375261cd484e4dd887613aa728703c2c.png

 开启慢查询日志,需要在MySQL的配置文件(/etc/my.cnf)中配置如下信息,同时重启mysql服务,使配置文件生效

# 开启MySQL慢日志查询开关

slow_query_log=1

# 设置慢日志的时间为2秒,SQL语句执行时间超过2秒,就会视为慢查询,记录慢查询日志 long_query_time=2

ad7047b43a154514a782a5383c7ba976.png

 查询600万数据的表

eee2fb613cf440e1812862c6adb66c24.png

 毫无疑问出现在慢查询日志上a25b6db262ed4c7fa437a364afaeea05.png

profile详情

show profiles 能够在做SQL优化时帮助我们了解时间都耗费到哪里去了。通过have_profiling 参数,能够看到当前MySQL是否支持profile操作:

#查询是否有profile参数
select @@have_profiling
#查询profile功能是否开启 0表示关闭 1表示开启
select @@profiling

cc3470d26ce14cf1a04b88efebc140cc.png

 可以看到,当前MySQL是支持 profile操作的,但是开关是关闭的。可以通过set语句在 session/global级别开启profiling:

SET profiling = 1;

 执行一系列的业务SQL的操作,然后通过如下指令查看指令的执行耗时:

# 查看每一条SQL的耗时基本情况
show profiles;
# 查看指定query_id的SQL语句各个阶段的耗时情况
show profile for query query_id;
# 查看指定query_id的SQL语句CPU的使用情况
show profile cpu for query query_id;

f9c78897baa14e0ba7c47c15a4d63817.png

explain

EXPLAIN 或者 DESC命令获取 MySQL 如何执行 SELECT 语句的信息,包括在 SELECT 语句执行 过程中表如何连接和连接的顺序。在select语句开头加上explain关键词即可,通过explain各字段的值,我们可以分析出此时的sql语句走不走索引,有没有回表查询等情况,方便我们进行sql优化

7159495b9656426c8f9e8527bcee28f5.png

 Explain 执行计划中各个字段的含义:

字段含义

id

select查询的序列号,表示查询中执行select子句或者是操作表的顺序

(id相同,执行顺序从上到下id不同,值越大,越先执行)。

select_type

表示 SELECT 的类型,常见的取值有 SIMPLE(简单表,即不使用表连接 或者子查询)、PRIMARY(主查询,即外层的查询)、 UNION(UNION 中的第二个或者后面的查询语句)、

SUBQUERY(SELECT/WHERE之后包含了子查询)等

type

表示连接类型,性能由好到差的连接类型为NULL、system、const、eq_ref、ref、range、 index、all 。

possible_key

显示可能应用在这次查询的索引,一个或多个。

key

实际使用的索引,如果为NULL,则没有使用索引。

key_len

表示索引中使用的字节数, 该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下, 长度越短越好。

rows

MySQL认为必须要执行查询的行数,在innodb引擎的表中,是一个估计值, 可能并不总是准确的。

filtered

表示返回结果的行数占需读取行数的百分比,filtered 的值越大越好。

 索引使用

效率验证

准备一张百万数据的表,根据id查询数据,我们可以发现此时耗时仅为0.01秒,这是因为id默认就是主键索引,这是已经有索引的查询情况

5cc44a84f8b1404693b2d776819da01a.png

 根据name字段查询时,此时没有建立name字段的索引,可以看到耗时达到6秒之久

0767130613884f31a5e4fee757174b84.png

建立索引之后,根据name查询,耗时仅有0.01秒,可见索引能大大提升查询效率

16da7e42c69448ba9c458cdc57346665.png

最左前缀法则

如果索引了多列(联合索引),要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始, 并且不跳过索引中的列。如果跳跃某一列,索引将会部分失效(后面的字段索引失效)。

以tb_user表为例,此时有idx_user_pro_age_sta这个联合索引,这个联合索引涉及到三个字段,顺序分别为:profession, age,status。

9ee1baad1e4c4c58be19a4f5803f1ac1.png

 对于最左前缀法则指的是,查询时,最左变的列,也就是profession必须存在,否则索引全部失效。 而且中间不能跳过某一列,否则该列后面的字段索引将失效。

explain select * from tb_user where profession = '软件工程' and age = 31 and status
= '0'

 联合索引的三个字段都在联合索引必然生效,只要where条件后面的三个字段都在索引就会生效,与字段的先后顺序无关c1a8a66093d84bfc9e34ecf2cfad24b1.png

 我们尝试profession后面的两个字段逐步减少,会发现联合索引仍然生效,正说明只要索引的最左边的字段在where子句中索引就会生效。从图中我们也可以推测出profession字段索引长度为47、age 字段索引长度为2、status字段索引长度为5。0b8902e66d4549c688b83a70ee02f112.png

 但此时我们将查询条件中的profession去掉,此时联合索引失效。

a14881ef6dad4f5dac66c0dcb5e1577f.png

 如果最左的列存在,但是跳过了中间的列,那么只会中间列之后的索引都不会生效,虽然走了联合索引,但长度只有47,为profession字段索引长度。

aafcdf3aae264c779169b2cabdab9813.png

 范围查询

联合索引中,出现范围查询(>,<),范围查询右侧的列索引失效。从索引长度可以看到status字段的索引并没有生效

7621835d4b11437abc299473739e755d.png

 但如果我们将范围查询加上等号即≥和≤这种形式,联合索引就生效,在业务允许的情况下,尽可能的使用类似于 >= 或<=,而避免使用 > 或 <,来避免索引失效

f1f5d236c114447e9eaf3942222e9fad.png

 索引失效情况

 索引列函数运算

当根据phone字段进行等值匹配查询时, 索引生效。

56d3207931ac46c18af0f73e8366d7ba.png

 当进行函数运算时,索引就失效,走的是全表扫描

f1f6a41b3f9c45d4abd8d93b2ae703df.png

如果进行的是数值运算,索引仍然生效

d3cc25844ead44fe9a3c6eb24bae6965.png

 字符串不加引号

如果不给phone字段添加引号,造成索引类型不匹配,索引也会失效

7bc723be16744d31bb30e2c049d5ac6b.png

 模糊查询

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

头部模糊查询,走的是全表扫描

8b473af81d804d8bbc15ea39e5118ea5.png

 如果是尾部模糊,则走联合索引,索引生效,如果前后模糊查询,由于前面模糊查询已使索引失效,所以也是索引失效

e15fd297ba7443a58b97516a970bd966.png

 or连接条件

用or分割开的条件, 如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会 被用到,因为or前面的用了索引,or后面的列没有索引还是要走全表扫描,mysql优化器就会判断直接全表扫描,避免浪费一次查找索引树的时间

数据分布影响

相同的SQL语句,只是传入的字段值不同,最终的执行计划也完全不一样,这是因为MySQL在查询时,会评估使用索引的效率与走全表扫描的效率,如果走全表扫描更快,则放弃索引,走全表扫描。 因为索引是用来索引少量数据的,如果通过索引查询返回大批量的数据,则还不 如走全表扫描来的快,此时索引就会失效。即数据分布情况也会影响索引是否生效

3d2c6523c97444b2a71549f0f26084a9.png

 SQL提示

sql提示就是在执行查询时我们自己指定要使用的索引

 此时我们有 profession这个字段的单列索引

cc3c342851174e1da0aa432f8a380b60.png

 我们可以看到,possible_keys中 idx_user_pro_age_sta,idx_user_pro 这两个 索引都可能用到,最终MySQL选择了idx_user_pro_age_sta索引。这是MySQL自动选择的结果。我们想看到的是走单列索引,毕竟我的mysql我做主,这时候就要用到sql提示啦!38065709f9424d3d924a36153a02c7d1.png

我们可以在select语句时加上use index(索引名)来建议mysql使用我们指定的索引(仅仅是建议,mysql内部还会再次进行评估)

2b20e99a3ad5489cbc1dbc42320bb1f1.png

 上面的use index 仅仅是建议,要是mysql不听怎么办?这时候就需要force index来强制mysql执行我们指定的索引!即使效率可能下降,但爷乐意,千金难买爷乐意,下图我们可以看到正常情况下肯定不会走sta索引的,毕竟我们where子句是根据profession来查的,但通过我们的强制,也能让mysql执行这一索引

28abba46eb4e4adf85ba09ba7271202e.png

覆盖索引

尽量使用覆盖索引,减少select *, 覆盖索引是指查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到。使用覆盖索引能减少能大大提高查询,其原因就是需要返回的列在索引列已经全部找到,不需要回表查询了,这也是mysql优先使用联合索引的原因

前缀索引

介绍

当字段类型为字符串(varchar,text,longtext等)时,有时候需要索引很长的字符串,这会让 索引变得很大,查询时,浪费大量的磁盘IO, 影响查询效率。此时可以只将字符串的一部分前缀,建 立索引,这样可以大大节约索引空间,从而提高索引效率。

 语法

create index idx_xxxx on table_name(column(n)) ;

为tb_user表的email字段,建立长度为5的前缀索引。

fee7b812272f4be8b8e587bf7ce91875.png

 前缀长度

可以根据索引的选择性来决定,而选择性是指不重复的索引值(基数)和数据表的记录总数的比值, 索引选择性越高则查询效率越高, 唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的。即要保证取得的前缀尽量唯一不重复。

 查询流程

前缀索引相当于二级索引,但他匹配到时,必须回表查询,确认根据前缀索引匹配到行数据的email值跟sql语句的email值是否一样,同时要遍历到链表的下一个元素,看是否与前缀索引匹配,如果是就要重复刚刚的流程然后返回数据,如果不是,直接返回数据即可

88f8c91cfabd49c8a157e95c90721512.png

 单列索引与联合索引

 前文提到的覆盖索引,mysql会优先使用联合索引,以此来减少回表查询,提高查询效率

单列索引:即一个索引只包含单个列。

联合索引:即一个索引包含了多个列。

 索引设计原则

1).针对于数据量较大,且查询比较频繁的表建立索引

2). 针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引。

3). 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。

4). 如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引。 5). 尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间, 避免回表,提高查询效率

6). 要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率,同时索引也会占用硬盘空间。 

7). 如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它。当优化器知道每列是否包含 NULL值时,它可以更好地确定哪个索引最有效地用于查询。

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

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

相关文章

使用Swift模拟用户登录当网获取数据并保存到MySQL中

前言 当当网作为中国最大的综合性网上商城之一&#xff0c;通过爬取当当网数据&#xff0c;我们可以获取商品信息、用户评价、销售数据等宝贵的信息资源。这些数据可以帮助企业了解市场趋势、分析竞争对手、优化产品定价等&#xff0c;从而做出更明智的决策。 为什么使用Swif…

3D网页游戏外包开发引擎

3D网页开发引擎是用于创建具有三维图形、虚拟现实和交互性的网页应用程序的工具。以下是一些常用的3D网页开发引擎以及它们的主要特点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.Three.js&…

Mysql设置了更新时间自动更新,指定更新部分sql时不进行时间更新

现象&#xff1a; 因为字段设置了自动更新&#xff0c;所以sql语句一进行修改此字段就会自动更新时间&#xff0c;但是呢我们的有部分定时任务是半夜执行&#xff0c;并且不能让这个任务修改到数据的更新时间 解决&#xff1a; <update id"updateCreative">ALT…

mac安装nodejs,跑vue程序

1. 下载node.js for mac&#xff0c;地址&#xff1a;Node.js。一路安装就可以了&#xff0c;无需修改。 2. mac终端&#xff0c;查看node和npm的版本。 3. 配置环境变量&#xff0c; vim .bash_profile增加PATH$PATH:/usr/local/bin/ 4. 但是毕竟npm安装一些东西还是太慢了所…

【网安AIGC专题10.19】论文6:Java漏洞自动修复+数据集 VJBench+大语言模型、APR技术+代码转换方法+LLM和DL-APR模型的挑战与机会

How Effective Are Neural Networks for Fixing Security Vulnerabilities 写在最前面摘要贡献发现 介绍背景&#xff1a;漏洞修复需求和Java漏洞修复方向动机方法贡献 数据集先前的数据集和Java漏洞Benchmark数据集扩展要求数据处理工作最终数据集 VJBenchVJBench 与 Vul4J 的…

Git基础命令实践

文章目录 简介git的安装配置git的安装git的配置 git使用的基本流程创建版本库时光机穿梭版本回退工作区和暂存区管理修改撤销修改删除文件 远程仓库添加远程库从远程库克隆 总结 简介 本文主要记录了我在学习git操作的过程&#xff0c;以及如何使用GitHub。建议先参考廖雪峰的…

计算机网络_04_传输层

文章目录 1.什么是传输层2.传输层提供了什么服务3.传输层协议TCP 1.什么是传输层 传输层是OSI七层体系架构中的第四层, TCP/IP四层体系架构中的第二层, 从通信和信息处理两方面来看&#xff0c;“传输层”既是面向通信部分的最高层&#xff0c;与下面的三层一起共同构建进行网…

飞利浦双串口51单片机485网关

主要功能将PC端的数据接收下来&#xff0c;分发到不同的设备&#xff0c;也是轮询设备数据读取回来&#xff0c;打包回传到PC端&#xff0c;数据包包头包尾识别&#xff0c;数据校验&#xff0c;接收超时处理&#xff0c;将协议结构化处理&#xff0c;协议的改动不需要改动程序…

【数据结构】Map和Set

Map和Set 1. 搜索树 1.1 概念 二叉搜索树是左子树比根节点小&#xff0c;右子树比根节点大的二叉树。&#xff08;如果左右子树不为空的话是这样&#xff0c;但是左右子树也可以为空&#xff09; 1.2 操作——查找 查找的思想与二分查找类似。 如果根节点的值和所要查找的…

前端知识与基础应用

前端知识 什么是前端&#xff1a;所有和用户打交道的操作页面&#xff0c;我们都称之为前端 例如&#xff1a;pc页面&#xff0c;浏览器的主页面&#xff0c;手机页面等等&#xff0c;可以用肉眼看到的就是前端 什么是后端&#xff1a; 就是一堆代码&#xff0c;用户不能够直接…

Kitex踩坑 [Error] KITEX: processing request error,i/o timeout

报错问题 2023/010/28 17:20:10.250768 default_server_handler.go:234: [Error] KITEX: processing request error, remoteService, remoteAddr127.0.0.1:65425, errordefault codec read failed: read tcp 127.0.0.1:8888->127.0.0.1:65425: i/o timeout 分析原因 Hert…

内置视图联动查看器,实现数据关联分析

前言 在数据驱动业务发展的今天&#xff0c;数据的关联分析变得越来越重要。作为一种强大的数据挖掘工具&#xff0c;它可以帮助企业发现数据之间的关联和模式&#xff0c;从而更好地理解市场和客户的行为。通过关联分析&#xff0c;企业可以发现看似无关的数据之间的联系&…

假如我有一台服务器,我会让它提供三种服务

一、提供照片上传、存储和下载服务 随着移动互联网时代的持续快速发展&#xff0c;PC互联网日益势微&#xff0c;各大互联网门户网站的博客、空间也跟着凋零&#xff0c; 作为博客、空间的标配功能的相册也随之被关闭。 2019年3月6日网易相册发布停运公告并于当年5月8日正式停…

在线主动学习算法评估策略:prequential evaluation procedure

在线主动学习算法评估策略&#xff1a;prequential evaluation procedure 在在线主动学习领域(Online Active Learning)&#xff0c;对在线主动学习算法的评估策略有多种方法&#xff0c;而现如今常用的方法是prequential evaluation procedure(出自论文《High density-focuse…

SpringBoot 源码分析(四) 内置Tomcat分析

一、Tomcat相关知识 1. tomcat目录结构 Tomcat文件的目录结构 2.启动流程 启动一个Tomcat服务是执行的bin目录下的脚本程序&#xff0c;startup.bat和 startup.sh.一个是windows的脚本&#xff0c;一个是Linux下的脚本&#xff0c;同样还可以看到两个停止的脚本 shutdown.ba…

Java入门与实践

Java基础 Java入门 idea的使用 idea快捷键 crtlaltt 对选中的代码弹出环绕选项弹出层 问题描述&#xff1a;idea光标变小黑块 解决&#xff1a;误触Insert键&#xff0c;再次按Insert键即可 java基础语法 注释 //单行注释/* 多行注释 *//** 文档注释&#xff0c;可提取到…

车载网关产品解析(附:车载网关详细应用案例及部署流程)

5G车载网关是一款功能强大的工业级无线通讯设备。它集成了4G/5G双模网络模块、M12接口设计、强大的路由和安全功能等特性,可以为车载和移动应用提供稳定可靠的无线数据连接。 链接直达&#xff1a;https://www.key-iot.com/iotlist/sv900.html ### 产品特性 5G车载网关最大的…

【多线程】线程互斥 {多执行流并发执行的数据竞争问题,互斥锁的基本用法,pthread_mutex系列函数,互斥锁的原理;死锁;可重入函数和线程安全}

一、进程线程间通信的相关概念 临界资源&#xff1a;多线程执行流共享的资源就叫做临界资源。确切的说&#xff0c;临界资源在同一时刻只能被一个执行流访问。临界区&#xff1a;每个线程内部&#xff0c;访问临界资源的代码&#xff0c;就叫做临界区。互斥&#xff1a;通过互…

计算机网络基础三

课程目标 理解路由表的作用 能够读懂路由表信息 能够使用图形抓包工具 wireshark 进行数据包的抓取 &#xff0c;如&#xff08; TCP/IP 的三次握手四次断开&#xff09; 一、路由表 思考&#xff1a; 什么是交换,什么是路由,什么是路由表&#xff1f;1. 交换是指同网络访…

Linux C语言开发-D15一维数组

数组&#xff1a;有一定顺序关系的数据类型相同变量的变量集合 形式&#xff1a;<存储类型> <数据类型> <数组名> [<表达式>] 数组名表示内存首地址&#xff0c;是一个地址常量&#xff0c;sizeof(数组名)是数组占用的总内存空间 编译时分配连续内存…