当前位置: 首页 > news >正文

mysql 散记:innodb引擎和memory引擎对比 sql语句少用函数 事务与长事务

innodb引擎和memory引擎对比

innodb引擎是索引组织表(B+树),memory引擎是堆组织表(数组)

memory引擎数据结构

在这里插入图片描述
图片来自极客时间 丁奇 MySQL实战45讲

对比

  • 内存表按照写入顺序 顺序存放,innodb表数据有序存放
  • 内存表重启mysql就没了,innodb重启了还在
  • 内存表锁粒度粗,表锁;innodb有行锁
  • 写入数据:内存表里有空位就可以随便放数据,innodb表要保证树的有序性,要在指定位置插入数据
  • 数据位置变化时,内存表所有索引都要改(因为每个索引都直接指向数据的物理位置),innodb只用改主键索引(二级索引存的是主键索引位置,不用改)
  • 内存表所有索引地位相同,arr[index]取数据;innodb表二级索引地位低于主键索引
  • 内存表每个元素类型相同,都是arr item的统一类型;innodb表每个字段类型可以不同

sql 语句:尽可能不使用函数条件

使用函数条件会导致索引优化不能用,引起全表扫描。因为函数字段破坏索引的有序性。比如:

select  id, name from t where id+1 > 200 (where部分是函数表达式,no no no)
select count(*) from t where month(time)=7; 

隐式转换

隐式类型转换

隐式类型转换也相当于函数处理,会导致索引无效,比如:

select * from tradelog where tradeid=110717; // tradeid是varchar类型
// 这个操作就相当于在做数值比较,tradeid会先转成int类型再和110717比较 等价  CAST(tradid AS signed int) = 110717;
// 这个语句会走全表扫描
隐式字符编码转换

隐式字符编码转换,比如:t1的字符集是utf8mb4,t2的字符集是utf8;utf8mb4是utf8的超集。两个表字段进行比较时,utf8会先调用函数转utf8mb4再比较

如果调用时函数作用在参数上就不影响索引选择,但函数作用在列上,就会导致索引失效

// 索引失效
select t2.* from t1, t2 where t1.aid=t2.aid and t1.id=2; 
// 步骤:在t1表上拿到t1.id这行aid(utf8mb4);到t2表上找到t2.aid=utf8mb4 aid对应的行,转换字符集 => 找CONVERT(t2.aid USING utf8mb4) = $(t1.aid).value(参数常量)
// 函数作用在索引字段上,索引失效// 不影响索引
select t1.c from t1, t2 where t1.aid=t2.aid and t2.id=4;
// 步骤:在t2表上拿到t2.id这行的aid(utf8);到t1表上找t1.aid=utf8 aid对应的行,转换字符集 => 找t1.aid=CONVERT($(t2.aid).value USING utf8mb4) (参数常量)
补充问题
`b` varchar(10) DEFAULT NULLselect * from table_a where b='1234567890abcd';
// 不是直接找不到,而是扫描行 找 然后 对比,最后发现找不到。执行步骤:截断查找1234567890(10位),innodb找到了回到server层对比,不相等,循环 最后失败

事务与长事务

ACID

Aatomicity原子性事务中的所有操作统一成功,统一失败 // 部分失败就需要回滚 undolog
Cconsistency一致性
Iisolation隔离性mvcc一致性视图
Ddurability持久性永久保存,故障恢复(redo log)
  • 存储引擎执行语句时默认都会开启事务;只读操作不开启事务

  • 读(select … for update, select … lock in share mode)写操作默认开启事务

  • 默认set autocommit=1 // 自动提交;如果业务设置了set autocommit=0需要显示的commit才能提交事务

    • set autocommit=0容易导致意外的长事务
  • begin;时只是做了记录,到执行第一条读写语句时才真正开启事务,分发事务ID

    • 只读事务部分发事务ID,事务ID是为了处理写操作冲突问题
  • 马上启动事务语句:start transaction with consistence snapshot; // 创建一致性视图

    • 可重复读级别下才有一致性视图,读已提交下该语句等价start transaction;

read view

innodb中有两种视图:mvcc 一致性视图、view 虚拟表

MVCC 一致性视图
  • MVCC是为了解决事务ACID中的I isolation隔离性出现的
  • 历史数据不是直接存在的,而是通过undo log版本链在需要时计算出来的
    • undo log 实现秒级快照

go 原子操作、加锁、MVCC多版本并发控制_mvcc golang-CSDN博客

当前读
begin; // 假设创建可重复读级别的视图// Q1:在undo log上,拿着活跃列表走过不可见事务直至找到第一个可见事务,读这条数据
select * from t where id = 5; // 可重复读// Q2:更新数据前都要查一次数据,读是当前读:读最新的数据
update table t set c = 6 where id = 5; // 当前读// 自己的update对自己可见,所以此时读到的数据是Q2更新后的数据,与Q1时不同
select * from t where id = 5; commit;

select … for update(写锁)、select … lock in share mode(读锁)也是当前读。

view 虚拟表

查询语句定义的虚拟表,相当于持久化的查询语句别名。在调用时执行查询语句并生成结果。

虚拟表只存储查询定义,不存储实际数据。

长事务的影响与排查

影响
  • 长期占用连接,内存不释放,变大

    • 内存不是在使用完后释放,而是在连接断开或重置时释放
  • 长事务阻塞后续操作,

    • 可能导致线程用满 // 都等着执行,但长事务占着资源
    • 可能引起后续查询慢,比如长事务update id=1的数据10万次,没执行完成时select * from t where id = 5;需要在undo log链表上往前找10万多次才能找到需要返回的数据
  • 主从延迟 主库执行长事务10分钟,再发到从库去执行

    • 无法应用从库并行复制能力
  • 崩溃恢复时间长 可能因为 长事务回滚

排查方法

  • 是否set autocommit=0

    • 随便查个业务,通过general_log看是不是没有commit
  • information_schema.Innodb_trx 监控这个表,看长事务阈值

    select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60
    

预防

  • 业务执行设置超时时间

  • 长事务会导致undo log很大,innodb_undo_tablespaces = 2(2个独立的表空间文件), 方便回滚清理

http://www.dtcms.com/a/275097.html

相关文章:

  • 光伏反内卷,股价大涨
  • 电子电气架构 --- 电动汽车的主旋律(48V区域架构)
  • 【2025/07/11】GitHub 今日热门项目
  • Python 第三方库的安装与卸载全指南
  • vue2和vue3响应式原理浅析--应付面试本人是懒得记
  • PyTorch中的torch.argmax()和torch.max()区别
  • 视觉SLAM学习笔记:g2o位姿优化实战
  • doker和网站部署
  • Matplotlib-多图布局与网格显示
  • [Reverse1] Tales of the Arrow
  • P1886 滑动窗口 /【模板】单调队列
  • 代码随想录|图论|10水流问题
  • Word表格默认格式修改成三线表,一劳永逸,提高生产力!
  • Sigma-Aldrich细胞培养实验方案 | 悬浮细胞系的传代培养
  • 【真实案例】CATCOM-100实战:铁路积水监测与智能预警
  • Wend看源码-DeerFlow(基于LangGraph 的DeepResearch框架)
  • [SL] Brutus Linux登入紀錄分析+MITRE ATTCK+linper.sh本地权限提升工具
  • 面向构件的编程(COP)深度解析:构建模块化系统的工程范式
  • Debian:从GNOME切换到Xfce
  • 二叉树的层次遍历(BFS)
  • ## SQLITE:多表(子母表)联合查询【DA_Project笔记】
  • 032_super关键字与父类访问
  • CSP-J/S 参赛选手注册报名流程
  • 如何应对风险和不确定性
  • 还在靠防火墙硬抗?网络安全需要从“单点防御“转向“系统化防护“!
  • AGV穿梭不“迷路”CCLinkIE转Modbus TCP的衔接技巧
  • 【AI大模型】超越RAG的搜索革命!分层框架让AI像专家团队一样深度思考
  • 三轴云台之三维重建算法篇
  • Microbiome:如何区分肠道中的有益菌?有害菌?
  • 嵌入式 数据结构学习 (六) 树、哈希表与内核链表