mybatisPlus的@TableLogic逻辑删除注解导致联合索引失效的坑
文章目录
- 1.问题
- 2.原因
- 3.解决方法
- 3.1 方法1
- 3.2 方法2
- 4. 建索引的几大原则
- 4.1.最左前缀匹配原则,非常重要的原则
- 4.2.=和in可以乱序
- 4.3.尽量选择区分度高的列作为索引
- 4.4.索引列不能参与计算,保持列“干净”
- 4.5.尽量的扩展索引,不要新建索引
- 5.好文分享
- 6.总结
1.问题
假设一个mysql的一张单表叫student数据量有500w左右,如果没有选择适当的列加索引的话,相关的查询就会全表扫描,使用的是mybatisPlus作为ORM框架,并且在实体上的逻辑删除字段del(0:否,1:是)上加了@TableLogic注解,那么StudentService中的业务查询代码如下所示:
this.getOne(Wrappers.<Student>lambdaQuery().eq(Student::getName, xxxx).eq(Student::getAddress,xxxx).last("limit 1"))
如果在student的name,address两列上建立了联合索引如下:
ALTER TABLE student ADD INDEX `index_name_address` (`name`,`address`); -- 索引默认是BTREE
请问各位看官上面那个StudentServer的this.getOne的查询有没有走index_name_address索引?
答案是:不会走索引,可以使用explain查根据上面业务代码的sql的执行计划
explain SELECT * FROM student WHERE name = 'xxxx' AND address = 'xxxxxx' LIMIT 1
如果按照上面的业务代码使用眼睛翻译的sql确实会认为是根据name和address两个条件来查的,但实际上却不是这种的,这里也是有点坑的,如果你以为是这种加索引的,那么即使是加了索引也不会走索引,在那么大数据量的表中加索引还是有风险的,那如何来处理解决呢? 请听下面分析讲解。
2.原因
首先可以将mybatisPlus的sql打印开开,然后在测试环境写一个test方法,测试下上面那个业务代码,把sql抓到,然后你就会豁然开朗了,开启mybatisPlus的sql打印日志配置如下:
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpltypeAliasesPackage: xxx.xxxx.entitymapper-locations: classpath:mapper/*.xml
在测试环境写一个test用例方法就省略了,抓到的sql如下:
SELECT * FROM student WHERE del = 0 AND ( name = 'xxxx' AND address = 'xxxxxx') LIMIT 1
问题的根本原因就是mybatisPlus使用了@TableLogic注解在实体中标注了逻辑删除字段,最终的sql会将逻辑删除的字符放在一个条件上,会导致联合索引失效(最左匹配的原则),如果生产表数据太大,sql索引失效导致全表扫描,在并发比较高的情况下,一个sql的慢会将mysql数据库cpu干到百分之好几百,导致业务系统不可用,验证可能直接把mysql数据库拖垮,这种就是生产级别的事故了。
3.解决方法
3.1 方法1
ALTER TABLE student ADD INDEX `index_del_name_address` (`del`,name`,`address`);
修改原索引
3.2 方法2
ALTER TABLE student ADD INDEX `index_name` (`name`);
ALTER TABLE student ADD INDEX `index_address` (`address`);
这种方式建议一开始就这种搞,生产单表数据量太大,不建议删除之前的索引后新增两个单列索引
4. 建索引的几大原则
4.1.最左前缀匹配原则,非常重要的原则
mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
4.2.=和in可以乱序
比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式。
4.3.尽量选择区分度高的列作为索引
区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录。
4.4.索引列不能参与计算,保持列“干净”
比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’)。
4.5.尽量的扩展索引,不要新建索引
比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。
总之,索引不是越多越好越快,而是加的恰到好处,所以遵循上面的原则来加是比较好的。
5.好文分享
https://www.bilibili.com/video/BV1UL411z7WD/?buvid=XX3844F3338BD8CFE89E44F906B4309A8CD6E&from_spmid=main.my-favorite.0.0&is_story_h5=false&mid=3McxpjV8dqbNqf%2FOSLyb1A%3D%3D&p=1&plat_id=116&share_from=ugc&share_medium=android&share_plat=android&share_session_id=3c6b1623-f34f-4fad-8b07-62e11e04b9f8&share_source=WEIXIN&share_tag=s_i&spmid=united.player-video-detail.0.0×tamp=1723546033&unique_k=XitSYec&up_id=3493270011251381https://www.cnblogs.com/zmc60/p/14533123.html
https://mp.weixin.qq.com/s/hcmRh493yWJUJTJl0tlZWw
https://tech.meituan.com/2014/06/30/mysql-index.html
6.总结
当生产单表数据量上百万级别的时候,如果要修改表结构的DDL操作,加索引这种操作都还是有一定的风险的,建议在业务低峰期操作,还是要相当的小心,尽量不要去随意操作,否则一个不小心就把系统搞挂了,那个可是要背锅的,mysql在表数据量非常大的时候能力就相对来说弱了一点,所以需要寻求强悍的在大数据量下的查询分析引擎方案,mysql、redis等单一数据库撸到底(可以尝试一些新东西,然后组合搭配使用)已经在这种大数据体量下力不从心了,所以就需要大数据的架构来解决大数据量的写入查询分析等痛点问题,本次分享到此结束,希望我的分享对你有所启发和帮助,请一键三连,么么么哒!
相关文章:
mybatisPlus的@TableLogic逻辑删除注解导致联合索引失效的坑
文章目录 1.问题2.原因3.解决方法3.1 方法13.2 方法2 4. 建索引的几大原则4.1.最左前缀匹配原则,非常重要的原则4.2.和in可以乱序4.3.尽量选择区分度高的列作为索引4.4.索引列不能参与计算,保持列“干净”4.5.尽量的扩展索引,不要新建索引 5.…...
C# 隐式转换和显式转换
在C#中编程语言中,数据类型转换是一个重要的概念,C#提供了两种主要的转换方式:隐式转换和显式转换。理解下这两种转换方式对于编写健壮和可靠的代码至关重要。 隐式转换(Implicit Conversion) 定义 隐式转换是指的是…...
入门网络安全工程师要学习哪些内容
大家都知道网络安全行业很火,这个行业因为国家政策趋势正在大力发展,大有可为!但很多人对网络安全工程师还是不了解,不知道网络安全工程师需要学什么?知了堂小编总结出以下要点。 网络安全工程师是一个概称,学习的东西很多&…...
深入理解 Go 并发原语
1. goroutine 基础知识 1.1 进程 进程(process) 是一个程序的实例,具有某些专用资源,如内存空间、处理器时间、文件句柄(例如,Linux 中的大多数进程都有 stdin、stdout 和 stderr) 和至少一个线程。我们称其为实例&am…...
计算机毕业设计选题推荐-springboot 基于springboot的宠物健康顾问系统
✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java实战 |…...
数据结构—— 初识二叉树
1.树概念及结构 1.1树的概念 树是由根和子树构成 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的 1. 树有…...
2024.08.09校招 实习 内推 面经
地/球🌍 : neituijunsir 交* 流*裙 ,内推/实习/校招汇总表格 1、校招 | 顺丰科技 2025届秋季校园招聘技术专场正式启动(内推) 校招 | 顺丰科技 2025届秋季校园招聘技术专场正式启动(内推) …...
IDEA中设置类和方法的注释
分两步设置: 第一个设置是创建类的时候自动加的注解 第二个设置是快捷键为方法增加的注解 类的时候自动加的注解设置 注释模版 #if (${PACKAGE_NAME} && ${PACKAGE_NAME} ! "")package ${PACKAGE_NAME};#end /** * Description: TODO * Auth…...
Adobe Premiere Pro 2023-23.6.7.1 解锁版下载与安装教程 (一款专业的视频编辑软件)
前言 Adobe Premiere Pro(简称PR)是一款知名的专业视频编辑软件,数字视频剪辑软件。主要用来编辑视频和音频,可以在RGB和YUV色彩空间中以高达32位色彩的视频分辨率对4K和更高质量的视频文件进行编辑,支持VST音频插件和…...
openGauss 6.0安装过程解除对root用户依赖之gs_preinstall
目录 1.执行前提条件 1.1设置OS参数: 1.2定时任务权限 1.3 修改最大文件描述符 2.切换至omm用户,执行preinstall 3.source环境变量 4.执行gs_install 在给客户部署业务系统时,由于openGauss数据库的预安装过程需要用到root用户执行&am…...
IOS 10 统一颜色管理和适配深色模式
实现分析 像系统那样,给项目中常用的颜色取名字,这里使用扩展语法实现,好处是可以像访问系统颜色那样访问自定义的颜色。 添加依赖 为了能使用16进制的颜色值,这里通过依赖DynamicColor框架来实现 #颜色工具类 #https://githu…...
Linux目录结构及基础查看命令和命令模式
Linux目录结构及基础查看命令和命令模式 1.树形目录结构根目录 所有分区、目录、文件等的位置起点整个树形目录结构中,使用独立的一个“/”表示 常见的子目录 /root 管理员的宿主(家)目录 /home/xxx 普通用户的家目录 /bin 命令文件目录,存放所…...
UDP和TCP协议段格式分析
目录 UDP协议 特点 UDP协议的缓冲区 UDP协议段格式 TCP协议 特点 如何理解TCP是传输控制协议? TCP协议段格式 四位首部长度 16位窗口大小 32位序号 32位确认序号 TCP/IP四层模型: UDP协议 UDP(User Datagram Protocol ÿ…...
Go语言基础--条件判断(if语句)
if语句它允许程序根据一个或多个条件(通常是布尔表达式)的真假来决定执行哪一段代码。如果条件为真(true),则执行if语句块内的代码;如果条件为假(false),则跳过该代码块&…...
白骑士的C#教学实战项目篇 4.2 图形用户界面(GUI)应用
系列目录 上一篇:白骑士的C#教学实战项目篇 4.1 控制台应用程序 在这一部分,我们将从简单的控制台应用程序过渡到图形用户界面(GUI)应用程序。GUI 应用程序更加直观和用户友好,是现代软件开发的核心内容。我们将介绍如…...
【Java学习】反射和枚举详解
所属专栏:Java学习 🍁1. 反射 在程序运行时,可以动态地创建对象、调用方法、访问和修改字段,以及获取类的各种属性信息(如成员变量、方法、构造函数等),这种机制就称为反射 反射相关的类 类名用…...
leetcode-461. 汉明距离
题目描述 两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。 给你两个整数 x 和 y,计算并返回它们之间的汉明距离。 示例 1: 输入:x 1, y 4 输出:2 解释: 1 (0 0 0 1) 4 (0 1 0 0) …...
rpmbuild 将二进制文件 strip,文件 md5 发生改变
rpmbuild 将二进制文件 strip,文件 md5 发生改变 上一篇中提到 strip 相关的操作,会去掉文件中的调试信息【strip 、objdump、objcopy 差异与区别】 在编译或打包环境中,莫名其妙的文件 大小 md5 都发生了改变,怀疑跟 rpmbuild 打…...
selenium爬取搜狗网站新闻的小Demo
使用之前请确保自己chrome浏览的版本与chromedriver的版本一致, Mac确保chromedriver已经放到python的bin目录中 Windows确保chromedriver已经放到python.exe同目录中 当前selenium Version: 3.141.0,4版本后面改为:find_element(By.CLASS_NA…...
R 语言学习教程,从入门到精通,R CSV 文件使用(17)
1、R CSV 文件 R 作为统计学专业工具,如果只能人工的导入和导出数据将使其功能变得没有意义,所以 R 支持批量的从主流的表格存储格式文件(例如 CSV、Excel、XML 等)中获取数据。 1.1、CSV 表格交互 CSV(Comma-Separ…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
