性能分析之MySQL索引实战案例

2024-09-09 17:44

本文主要是介绍性能分析之MySQL索引实战案例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、前言
  • 二、准备
  • 三、MySQL索引优化
  • 四、MySQL 索引知识回顾
  • 五、总结

一、前言

在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引?

  • 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP

二、准备

打开IDEA找到登录请求资源路径位置,代码如:

@PostMapping(value = "/login")
public BaseResponseInfo login(@RequestParam(value = "loginName", required = false) String loginName,@RequestParam(value = "password", required = false) String password,HttpServletRequest request)throws Exception {

**步骤1:**找到登录 Controller 调 service 位置
在这里插入图片描述

**步骤2:**找到方法实现层:
在这里插入图片描述
解释:
从上面代码可以看出,用户登录传入用户名密码,代码根据用户去DAO层去查询是否有该用户;
在这里插入图片描述
说明:Dao层就是常规写法,没有什么特别地方,再跳转xml文件查看SQL是怎么写的:
在这里插入图片描述

说明:根据条件查询全部数据,既然这是登录接口传入的是用户名,那么应该在用户名处增加用户索引,这样查询能加快速度;

索引类似于字典目录,通过索引能快速找到响应数据;

在这里插入图片描述
解释:
如果查询为空或者查询结果为0表示数据库么有数据直接返回用户不存在,如果存在在往下走走;
在这里插入图片描述
解释:
如果上面都通过,这里又根据用户名密码查询数据库,这里作者为什么要查询两次数据库,既然上面已经查询完全可以在内存做判断;假如数据库有1000千用户数,每个用户登录都需要查询两次数据,也是一笔不小的开支;

三、MySQL索引优化

上面已经发现索引有问题,但是发现用户表数据很少,第一步先增加用户数据,再通过JMeter进行压测,造数据在性能测试中是常见的事件,这次造数据直接通过 java for 循环造数据,代码参考如下:


/*** @description: 注册用户* @author: 李文* @create: 2021-03-19 21:03**/
@RunWith(SpringRunner.class)
@SpringBootTest
public class LoginRegTest {@Resourceprivate UserMapper userMapper;@Testpublic void contextLoads() {try {for (int j = 0; j < 100; j++) {for (int i = 0; i < 1000; i++) {UserEx userEx = new UserEx();userEx.setLoginName(RandomUtil.randomString(10));userEx.setUsername(RandomUtil.randomString(8));userEx.setEmail(RandomUtil.randomInt(1, 1100) + "@7DGroup.com");userEx.setPassword(Tools.md5Encryp(BusinessConstants.USER_DEFAULT_PASSWORD));userEx.setIsystem(BusinessConstants.USER_NOT_SYSTEM);userEx.setIsmanager(BusinessConstants.USER_NOT_MANAGER);userEx.setStatus(BusinessConstants.USER_STATUS_NORMAL);userMapper.insert(userEx);}}} catch (NoSuchAlgorithmException e) {e.printStackTrace();}}
}

再次打开MySQL客户端输入如下SQL语句:

mysql> SELECT count(*) from `jsh_user`;
+----------+
| count(*) |
+----------+
| 333724   |
+----------+
1 行于数据集 (0.07)mysql> SELECT count(*) from `jsh_user`;EXPLAIN SELECT id,username,login_name, PASSWORD,position, department, email, phonenum, ismanager, isystem, STATUS, description, remark, tenant_id
FROMjsh_user
WHERE(login_name = "admin"AND PASSWORD = "e10adc3949ba59abbe56e057f20f883e"AND STATUS = 0);
+----------+
| count(*) |
+----------+
| 333724   |
+----------+
1 行于数据集 (0.05)+----+-------------+----------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table    | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra       |
+----+-------------+----------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| 1  | SIMPLE      | jsh_user | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 331551 | 0.10     | Using where |
+----+-------------+----------+------------+------+---------------+------+---------+------+--------+----------+-------------+
1 行于数据集 (0.06)mysql> 

截图如下:
在这里插入图片描述
为了减少性能消耗,这次都采用后台运行,把项目跑起来显示如下:
在这里插入图片描述
JMeter运行结果如下:
在这里插入图片描述

liwen@liwen123 hunhe % jmeter -n -t he1.jmx
Creating summariser <summary>
Created the tree successfully using he1.jmx
Starting standalone test @ Fri Mar 19 22:01:53 CST 2021 (1616162513949)
Waiting for possible Shutdown/StopTestNow/HeapDump/ThreadDump message on port 4445
summary +     44 in 00:00:06 =    7.8/s Avg:   534 Min:   472 Max:   910 Err:     0 (0.00%) Active: 9 Started: 9 Finished: 0
summary +    336 in 00:00:30 =   11.2/s Avg:  2129 Min:   537 Max:  3626 Err:     0 (0.00%) Active: 30 Started: 30 Finished: 0
summary =    380 in 00:00:36 =   10.7/s Avg:  1944 Min:   472 Max:  3626 Err:     0 (0.00%)

运行几分钟结果如下:
在这里插入图片描述
MySQL增加索引语句:

ALTER TABLE `jsh_user` ADD INDEX index_name ( `login_name` )

增加索引结果如下:

在这里插入图片描述
调优结果:

在这里插入图片描述
JMeter后台数据如下:

在这里插入图片描述
说明:
通过直接增加索引TPS明显增加;

四、MySQL 索引知识回顾

MySQL索引分为:
(1)主键索引 PRIMARY KEY:它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引。
(2) 唯一索引 UNIQUE:

ALTER TABLE table_name ADD UNIQUE (column)

(3) 普通索引 INDEX

ALTER TABLE table_name ADD INDEX index_name (column)

(4) 组合索引 INDEX

ALTER TABLE table_name ADD INDEX index_name(column1, column2, column3)

(5) 全文索引 FULLTEXT

ALTER TABLE table_name ADD FULLTEXT (column)

查看索引:

mysql> show index from  jsh_user;
+----------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| Table    | Non_unique | Key_name   | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible |
+----------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
| jsh_user | 0          | PRIMARY    | 1            | id          | A         | 3           | NULL     | NULL   |      | BTREE      |         |               | YES     |
| jsh_user | 1          | index_name | 1            | login_name  | A         | 331551      | NULL     | NULL   |      | BTREE      |         |               | YES     |
+----------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+
2 行于数据集 (0.02)mysql>

删除索引:

ALTER TABLE  jsh_user DROP INDEX  index_name;

更多MySQL性能分析请参考《性能测试实战30讲》中的:

  • 《22丨MySQL:数据库级监控及常用计数器解析(上)》
  • 《23丨MySQL:数据库级监控及常用计数器解析(下)》

五、总结

性能优化是一个反复验证尝试的过程,但调优步骤是有逻辑。在这一节中通过观察代码步骤来跟踪并理解为什么在用户名上面增加索引,通过边压测边增加索引看到调优结果。

相关系列:

  • 性能工具之 JMeter ajax 简单登录案例实战
  • 性能工具之 JProfiler 简单登录案例分析实战

这篇关于性能分析之MySQL索引实战案例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

通过Docker Compose部署MySQL的详细教程

《通过DockerCompose部署MySQL的详细教程》DockerCompose作为Docker官方的容器编排工具,为MySQL数据库部署带来了显著优势,下面小编就来为大家详细介绍一... 目录一、docker Compose 部署 mysql 的优势二、环境准备与基础配置2.1 项目目录结构2.2 基

Linux安装MySQL的教程

《Linux安装MySQL的教程》:本文主要介绍Linux安装MySQL的教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux安装mysql1.Mysql官网2.我的存放路径3.解压mysql文件到当前目录4.重命名一下5.创建mysql用户组和用户并修

MySQL中慢SQL优化的不同方式介绍

《MySQL中慢SQL优化的不同方式介绍》慢SQL的优化,主要从两个方面考虑,SQL语句本身的优化,以及数据库设计的优化,下面小编就来给大家介绍一下有哪些方式可以优化慢SQL吧... 目录避免不必要的列分页优化索引优化JOIN 的优化排序优化UNION 优化慢 SQL 的优化,主要从两个方面考虑,SQL 语

Python实现将MySQL中所有表的数据都导出为CSV文件并压缩

《Python实现将MySQL中所有表的数据都导出为CSV文件并压缩》这篇文章主要为大家详细介绍了如何使用Python将MySQL数据库中所有表的数据都导出为CSV文件到一个目录,并压缩为zip文件到... python将mysql数据库中所有表的数据都导出为CSV文件到一个目录,并压缩为zip文件到另一个

如何解决mysql出现Incorrect string value for column ‘表项‘ at row 1错误问题

《如何解决mysql出现Incorrectstringvalueforcolumn‘表项‘atrow1错误问题》:本文主要介绍如何解决mysql出现Incorrectstringv... 目录mysql出现Incorrect string value for column ‘表项‘ at row 1错误报错

Mysql中深分页的五种常用方法整理

《Mysql中深分页的五种常用方法整理》在数据量非常大的情况下,深分页查询则变得很常见,这篇文章为大家整理了5个常用的方法,文中的示例代码讲解详细,大家可以根据自己的需求进行选择... 目录方案一:延迟关联 (Deferred Join)方案二:有序唯一键分页 (Cursor-based Paginatio

MySQL中慢SQL优化方法的完整指南

《MySQL中慢SQL优化方法的完整指南》当数据库响应时间超过500ms时,系统将面临三大灾难链式反应,所以本文将为大家介绍一下MySQL中慢SQL优化的常用方法,有需要的小伙伴可以了解下... 目录一、慢SQL的致命影响二、精准定位问题SQL1. 启用慢查询日志2. 诊断黄金三件套三、六大核心优化方案方案

Python实战之屏幕录制功能的实现

《Python实战之屏幕录制功能的实现》屏幕录制,即屏幕捕获,是指将计算机屏幕上的活动记录下来,生成视频文件,本文主要为大家介绍了如何使用Python实现这一功能,希望对大家有所帮助... 目录屏幕录制原理图像捕获音频捕获编码压缩输出保存完整的屏幕录制工具高级功能实时预览增加水印多平台支持屏幕录制原理屏幕

Redis中高并发读写性能的深度解析与优化

《Redis中高并发读写性能的深度解析与优化》Redis作为一款高性能的内存数据库,广泛应用于缓存、消息队列、实时统计等场景,本文将深入探讨Redis的读写并发能力,感兴趣的小伙伴可以了解下... 目录引言一、Redis 并发能力概述1.1 Redis 的读写性能1.2 影响 Redis 并发能力的因素二、

SQL Server清除日志文件ERRORLOG和删除tempdb.mdf

《SQLServer清除日志文件ERRORLOG和删除tempdb.mdf》数据库再使用一段时间后,日志文件会增大,特别是在磁盘容量不足的情况下,更是需要缩减,以下为缩减方法:如果可以停止SQLSe... 目录缩减 ERRORLOG 文件(停止服务后)停止 SQL Server 服务:找到错误日志文件:删除