数据量较小的表是否有必要添加索引问题分析

目录

    • 前言
    • 一、分析前准备
      • 1.1、准备测试表和数据
      • 1.2、插入测试数据
      • 1.3、测试环境说明
    • 二、具体业务分析
      • 2.1、单次查询耗时分析
      • 2.2、无索引并发查询服务器CPU占用率分析
      • 2.3、添加索引并发查询服务器CPU占用率分析
    • 三、总结

前言

      在一次节日活动我们系统访问量到达了平时的两倍,我们线上高峰期数据库CPU使用率从平常的20%左右飙升到了65%左右,数据库用的是阿里云的RDS-MySQL配置是32核 128G,并且为了应对活动我们还开启了SQL洞察(用于分析SQL的执行时间、次数、耗时比等),通过耗时比例能找到一个SQL占用整体耗时比例极高,并且执行次数比例不高,数据扫描行挺高的接近40w,查询调整是没有索引的,但是平均查询耗时在230ms并没有触发我们的慢SQL阈值,从平均查询耗时来看好像没什么问题,但是如果这张表是一张访问频率很高的表,那么问题就大了,最开始这张表预计存储数据量在1k左右,因为后面业务发展表的数据量有所增长,虽然单次查询耗时不高,但是扫描行很高导致CPU使用率飙升,下面开始对数据量很小的表是否有必要添加索引问题分析。

一、分析前准备

1.1、准备测试表和数据

    这里准备一个门店信息表。

CREATE TABLE `shop_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '门店ID',
  `origin_id` varchar(100) DEFAULT NULL COMMENT '门店唯一编号',
  `phone` varchar(100) DEFAULT NULL COMMENT '手机号',
  `location` varchar(100) DEFAULT NULL COMMENT '门店经纬度',
  `city_info` varchar(100) DEFAULT NULL COMMENT '城市信息',
  `create_time` bigint(20) DEFAULT NULL COMMENT '创建日期',
  `update_time` bigint(20) DEFAULT NULL COMMENT '更新日期',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='门店信息表';

1.2、插入测试数据

    我这里在表里面插入了1000条数据用于测试,我这里用的MyBatis-Plus只提供核心业务插入代码,有需要自己插入即可。

    public void batchInsert(int num) {
        ArrayList<ShopInfo> shopInfos = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            ShopInfo shopInfo = new ShopInfo();
            shopInfo.setOriginId(RandomUtil.randomString(20));
            shopInfo.setPhone("186"+RandomUtil.randomNumbers(8));
            shopInfo.setLocation("114."+RandomUtil.randomNumbers(6)+","+"23."+RandomUtil.randomNumbers(6));
            shopInfo.setCityInfo("xxx");
            long time = System.currentTimeMillis();
            shopInfo.setCreateTime(time);
            shopInfo.setUpdateTime(time);
            shopInfos.add(shopInfo);
        }
        this.saveBatch(shopInfos);
    }

1.3、测试环境说明

  • 服务器:阿里云CentOS7 2核4G
  • 数据库:MySQL8.0
  • 测试客户端:SpringBoot + MyBatis-Plus + druid

这里测试时我是通过本地直接连接云服务进行的测试,部分耗时可能会高一点。

二、具体业务分析

2.1、单次查询耗时分析

    这里我进行了多次查询,每次查询基本上都在0.13s左右,查询响应时间还能接受。

SELECT * FROM shop_info WHERE origin_id = "trj3arga4b5xsf4c5ie7";

在这里插入图片描述

2.2、无索引并发查询服务器CPU占用率分析

  • 1、通过top -p pid可以看到当前MySQL占用CPU为0

在这里插入图片描述

  • 2、并发查询测试,这里线程池核心线程数为100,数据源的最大连接数设置的也为100
    @Test
    public void t1() throws InterruptedException {
        // 查询出所有的门店数据用于测试查询
        List<ShopInfo> list = shopInfoService.list();
        List<String> originIdList = list.stream().map(ShopInfo::getOriginId).collect(Collectors.toList());

        long startTime = System.currentTimeMillis();// 开始时间戳

        ThreadPoolExecutor executor = new ThreadPoolExecutor(100, 100, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
        int num = 10000;
        CountDownLatch countDownLatch = new CountDownLatch(num);
        for (int i = 0; i <num; i++) {
            executor.execute(()->{
                ShopInfo shopInfo = shopInfoService.selectByOriginId(originIdList.get(RandomUtil.randomInt(originIdList.size() - 1)));
                log.info("shopInfo:{}",shopInfo);
                countDownLatch.countDown();
            });
        }
        countDownLatch.await();
        executor.shutdown();
        long endTime = System.currentTimeMillis();// 结束时间戳

        log.info("查询耗时:{}",endTime - startTime);
    }
2024-05-23 18:19:25.747 |  INFO [            main] com.kerwin.dbshop.ShopInfoTest   63 -| 查询耗时:8669

这里10000次查询耗时8669毫秒。

  • 3、查询时MySQL占用CPU峰值达到了90%多

在这里插入图片描述

2.3、添加索引并发查询服务器CPU占用率分析

    这里给origin_id字段添加一个普通索引。

ALTER TABLE `shop_info` ADD INDEX `idx_origin_id`(`origin_id`);
  • 1、添加索引后单次查询耗时在0.117s的样子,比不加索引只快了一点,因为数据量比较少单次查询耗时不明显。

在这里插入图片描述

  • 2、并发查询测试,测试代码和之前一样
2024-05-23 18:30:59.734 |  INFO [            main] com.kerwin.dbshop.ShopInfoTest  63 -| 查询耗时:7754

这里不加索引和加索引并发查询耗时其实区别不大,因为数据量比较少,而且MySQL也会将读取出来的数据进行缓存处理,走索引快速定位某一行和全表扫描在我这个测试程序下查询耗时区别很小。

  • 3、查询时MySQL占用CPU峰值只有32.3%,相比于不加索引CPU使用率降低了非常多。
    在这里插入图片描述

三、总结

  • 通过上面不太全面的分析,大致可以得出一个结论,被频繁访问的小表如果没有索引,那么高并发查询时CPU使用率会非常高,添加上对应查询索引后CPU使用率下降了非常多。

  • 当然并不是所有小表都适合或者说有必要加索引,比如表数据非常少,预计最多几十条添不添加其实没什么差别,就算全表扫描和走索引区别也不大,可以加但是没太大必要,索引查询后还需要根据数据ID进行回表查询,MySQL优化器可能会选择直接进行全表扫描,还有一些情况其实不适合添加索引,比如查询字段为大量重复数据的列,比如状态字段(启用、停用),这种类型的字段区分度不高不适合作为查询的索引,不过也要分业务,在某些时候可能的确需要。

  • 再换个思路,一般什么样的表数据量会比较少?一般都是一些配置表、方案表等,而这些类型的表都有一个特点,数据变化不频繁,而数据变化不频繁的配置信息是非常合适添加一个中间缓存的比如Redis,那么就算配置表有1000条数据,那么将活跃数据缓存到Redis中那么流量就不会打到数据库了,那么对于这样的设计,会被频繁访问小表也是可以不用添加索引的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

50道题目!Python、SQL数据库、AB测试、业务分析、机器学习都在这里了!

介绍 每日一题系列已经更新了50道题目啦&#xff01; 题目难度为初级到中级&#xff0c;涵盖了Python、SQL数据库、AB测试、业务分析、机器学习五大主题&#xff0c;适合初学者和有一定基础的朋友。 原文链接: 50道题目&#xff01;Python、SQL数据库、AB测试、业务分析、机器…

达梦数据库详解

达梦认证是指针对中国数据库管理系统&#xff08;DBMS&#xff09;厂商达梦公司所推出的数据库产品&#xff0c;即达梦数据库&#xff08;DMDB&#xff09;&#xff0c;进行的一种官方认证体系。达梦认证旨在验证数据库管理人员对达梦数据库产品的掌握程度&#xff0c;及其在数…

LoRA:大型语言模型的低秩适应

LoRA 官网 LoRA(Low-Rank Adaptation)出自2021年的论文“LoRA: Low-Rank Adaptation of Large Language Models” 常见的大模型微调方法&#xff1a; Adapter-Tuning、Prefix-Tuning、Prompt-Tuning(P-Tuning)、P-Tuning v2、LoRA。 LoRA技术冻结预训练…

冬奥会|基于SprinBoot+vue的冬奥会科普平台(源码+数据库+文档)

目录 基于SprinBootvue的冬奥会科普平台 一、前言 二、系统设计 三、系统功能设计 1登录注册 2系统功能模块 3管理员功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|…

Discourse 使用 DiscourseConnect 调用接口 admin/users/sync_sso 404 错误

在对用户数据通过 SSO 同步的时候&#xff0c;调用提示 404 错误。 我们使用的是 Java 的代码。 2024-05-23_16-34-421340802 70.3 KB 如上图&#xff0c;返回显示的代码为 404。 问题原因 出现上面错误的原因是安装的 Discourse 实例的 discourse connect 没有启用。 2024-…

【C语言】明析部分C语言内存函数

目录 1.memcpy 2.memmove 3.memset 4.memcmp 以下都是内存函数&#xff0c;作用单位均是字节 1.memcpy memcpy是C/C语言中的一个内存拷贝函数&#xff0c;其原型为&#xff1a; void* memcpy(void* dest, const void* src, size_t n);目标空间&#xff08;字节&#xff09…

作家百度百科怎么做出来的 怎么创建作家百科词条才能通过

创建作家百度百科词条需要遵循一定的步骤&#xff0c;并注意一些关键点&#xff0c;以确保词条能够顺利通过审核。以下是伯乐网络传媒pouquan根据经验结果得出的详细指导&#xff1a; 准备工作 注册百度账号&#xff1a;在创建任何百度百科词条之前&#xff0c;您需要先注册一…

Milvus的内存索引

简介&#xff1a; 这篇文章主要介绍milvus支持的各种内存索引&#xff0c;以及它们最适用的场景&#xff0c;还有用户为了获得更好的搜索性能可以配置的参数。 索引是有效组织数据的过程&#xff0c;它的主要角色是在大的数据集中显著的加速耗时的查询从而有效的进行相似搜索…

常见的100个Shell命令,超级实用!

在大多数的Linux和Unix系统、及其他类Unix系统中&#xff0c;Shell是用户与操作系统内核交互的主要方式。作为一种强大的命令行解释器&#xff0c;它也支持编程功能&#xff0c;用户可以写脚本来处理各种任务。 熟悉shell脚本&#xff0c;首先要对shell指令熟悉&#xff0c;今…

Python图形界面(GUI)Tkinter笔记(八):用【Label()】方法制作九九乘数表

主要是使用"config()"方法来体现函数式、模块化的美好风景。把需随时要修改的控件参数定义在“config()”方法里且把它封装在一个函数中&#xff0c;这时只需对这函数内的“config()”方法作出相应的修改即可&#xff0c;无需对主代码或全部代码重新修一遍。这也是Py…

【Spring】spring入门程序

案例要求&#xff1a;创建一个 Studentservice 类&#xff0c;其中需要使用 studentDao 接口的保存方法&#xff0c;来存储一个Student 类的对象&#xff0c;StudentDao 接口有两个不同的实现类&#xff0c;通过 Spring 的方式&#xff0c;为 Student类创建对象并为属性赋值&am…

react【框架原理详解】JSX 的本质、SyntheticEvent 合成事件机制、组件渲染过程、组件更新过程

JSX 的本质 JSX 代码本身并不是 HTML&#xff0c;也不是 Javascript&#xff0c;在渲染页面前&#xff0c;需先通过解析工具&#xff08;如babel&#xff09;解析之后才能在浏览器中运行。 babel官网可查看 JSX 解析后的效果 更早之前&#xff0c;Babel 会把 JSX 转译成一个 R…

论文精读:UFO: A UI-Focused Agent for Windows OS Interaction

UFO : A UI-Focused Agent for Windows OS Interaction Status: Reading Author: Bo Qiao, Chaoyun Zhang, Dongmei Zhang, Liqun Li, Minghua Ma, Qinglong Zhang, Qingwei Lin, Saravan Rajmohan, Shilin He, Si Qin, Xiangyu Zhang, Yu Kang Institution: 微软&#xff08;…

骑行之旅,骑行之旅,骑行之旅

骑行之旅其一&#xff1a;晨曦破晓普吉路&#xff0c;铁骑奔腾向远方。小桃园中寻雅趣&#xff0c;保利春湖泛波光。落水洞边环水库&#xff0c;田冲村里话家常。秧草塘畔风情美&#xff0c;白泥塘中歌声扬。陡普鲁村享盛宴&#xff0c;AA 制下笑语长。赛道体验激情涌&#xff…

有什么免费的文字转语音软件?这5个文字转语音工具超简单

听说你对最近备受瞩目的文字转语音技术很感兴趣&#xff1f; 文字转语音技术&#xff0c;就是一种将文本转换为自然语音的技术&#xff0c;它让机器发音听起来就像真人一样。那么&#xff0c;市面上的文字转语音软件种类繁多&#xff0c;选择起来就有些困难了。 别担心&#…

【cocos creator】进度条控制脚本,支持节点进度条,图片进度条,进度条组件,和进度文字展示

进度条控制脚本&#xff0c;支持节点进度条&#xff0c;图片进度条&#xff0c;进度条组件&#xff0c;和进度文字展示 const { ccclass, property, menu } cc._decorator;let text_type cc.Enum({"20%": 0,"1/5": 1,"差值": 2,"自定义…

开放式耳机怎么选择!教你几招!2024开放式蓝牙耳机推荐

在面对市场上琳琅满目的开放式耳机时&#xff0c;许多用户可能会感到难以抉择。作为一名开放式耳机的爱好者&#xff0c;我根据自己的实际使用体验&#xff0c;整理了一些我认为值得推荐的开放式耳机&#xff0c;希望能为正在寻找合适耳机的朋友们提供一些参考和帮助。我将为大…

Nodejs+Websocket+uniapp完成聊天

前言 最近想做一个聊天&#xff0c;但是网上的很多都是不能实现的&#xff0c;要么就是缺少代码片段很难实现websocket的链接&#xff0c;更别说聊天了。自己研究了一番之后实现了这个功能。值得注意的是&#xff0c;我想在小程序中使用socket.io&#xff0c;不好使&#xff0…

英语学习笔记24——Give me/us/him/her/them some ...

Give me/us/him/her/them some … 给我/我们/他/她/他们一些…… 词汇 Vocabulary desk n. 课桌&#xff08;有书桌堂&#xff09;&#xff0c;写字台 复数&#xff1a;desks 搭配&#xff1a;desk mate 同桌    构成&#xff1a;desk mate 桌子上的伙伴 同桌    cl…

深度学习模型keras第二十三讲:在KerasCV中使用SAM进行任何图像分割

1 SAM概念 ###1.1 SAM定义 Segment Anything Model&#xff08;SAM&#xff09;是一种基于深度学习的图像分割模型&#xff0c;其主要特点包括&#xff1a; 高质量的图像分割&#xff1a;SAM可以从输入提示&#xff08;如点、框、文字等&#xff09;生成高质量的对象掩模&am…