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

MySQL中text类型对查询效率的影响

背景

任何设计都需要结合实际的需求或者说系统来做,我们现在服务端的整体设计趋向于领域驱动模型(DDD)。将业务抽象划分成各个独立领域对象,各个领域各尽其职,只负责自己领域的工作。回到MySQL设计,在我们将业务关系转化为各个具体的实体时,同样秉承一个领域对象只负责自己领域的工作,数据库每张表设计落地后,也只会存储表对应的实体的属性。
当然,有时为了方便检索数据库中的数据,会在设计数据库时适当添加冗余字段(扩展字段),以空间换取时间。所以,我们系统中针对带有exten_info字段的查询接口性能都较差一点。还有一点是我们现在服务端的查询大部分带有连表查询,如果连大表级别也会有性能问题。

  • MySQL中对于blob,text,varchar(5120)这样的大字段,innodb只会存放前768字节在数据页中,而剩余的数据则会存储在溢出段中(发生溢出情况的时候),最大768字节的作用是便于创建前缀索引/prefix index,其余更多的内容存储在额外的page里,哪怕只是多了一个字节。因此查询这条记录会增加一次 io 操作。至于表设计是否需要大字段,需结合系统业务和实际情况;
    • 存大字段前尽量精简,保留重要且有用的信息;
    • 按需查询:搜索中如果不涉及到表中大字段就不进行查询;
    • 如果涉及到查询的列就尽量以新列存储;

参考:https://www.cnblogs.com/wqbin/p/11927456.html,MySQL 8.0

设计规范

  1. 禁止使用SELECT *;
  2. SQL语句中使用外连接时,尽量避免(join后面带)子查询,例如:join (select * from table)。特别是对于返回结果集比较大的子查询,其对查询性能的影响也就越大,由于子查询会产生大量的临时表也没有索引,所以会消耗过多的CPU和IO资源,产生大量的慢查询;其次,子查询的结果集无法使用索引,通常子查询的结果集会被存储到临时表中,不论是内存临时表还是磁盘临时表都不会存在索引,所以查询性能会受到一定的影响;
  3. 主键建议使用8字节无符号的bigint(20)作为主键的数据类型,提高查询效率,存储的顺序也是有序的,往远了看,分库分表也是有好处;
  4. 应该尽量使用可以正确存储数据的最小数据类型,因为它们占更少的磁盘,内存和CPU缓存,处理时需要的CPU周期也更少,比如状态、逻辑删除;(可能涉及数据库适配,可以选择“兼容”类型)
  5. 隐式转换会导致索引失效(现阶段Mapper中没有使用”定值“,不会出现该情况)。例如:
    select name from user where id = ‘111’;
  6. 对于频繁的查询优先考虑使用覆盖索引,但覆盖索引有利有弊(现阶段没有可以使用覆盖索引的需求);
    参考
  7. 代码层面上,禁止在循环体中调用外部接口、调用数据库或者进行数据持久化操作,减少同数据库的交互次数,数据库更适合处理批量操作;
  8. 硬件优化。。。

优化建议

1.列表查询均不使用扩展字段(类型数据为text、varchar(1024~)、blob等),如果列表展示内容,查询项,均需要横向扩展到表中;
2.精简存储数据库表的扩展字段字段内容;
综上,之前从exten_info获取的信息需要额外新增字段存储,或者单独存储其他表。

优化效果

优化前:
在这里插入图片描述
优化后:
以下是每页20条数据,每页数越少效果越佳:
[图片]

每页10条数据:
[图片]

结论

对于 blob,text这样的不定长大字段或者varchar长度过大的字段,innodb 只会存放前 768 字节在数据页中,而剩余的数据则会存储在溢出段中,对于行溢出数据会存储在额外的page里,也就是FIL_PAGE_TYPE_BLOB(溢出页),哪怕只是多了一个字节。因此查询这条记录会增加一次 io 操作,数据量越大,影响效果越明显。InnoDB中,理论上行记录最大长度为8KB(实际上要小于8KB,因为页中还有其他的数据结构占用空间),所以一行的数据长度之和大于8KB时,也会出现行溢出。
此外,MySQL(InnoDB)中存储数据的最小单位是页,一页能存储16KB大小的数据,且最少能存2条数据(参考),所以如果一条记录中长度和比较大的时候,就会根据行格式处理溢出数据:

  • Compact和Redundant行格式中,记录的真实数据处会存储该列的一部分数据(前768个字节), 剩余数据存储在其他页(溢出页),再使用20个字节存储指向溢出页的地址;
  • Dynamic(MySQL默认)和Compressed行格式中,不会在记录的真实数据处存放前768个字节,而是将所有字节都存储在其它页面中,自身只存储一个指向溢出页的地址;略有不同的是,Compressed 行格式会采用压缩算法对页面进行压缩,以节省空间。

言而总之,要么存 前缀+溢出页地址,要么只存 溢出页地址。
所以,查询这类数据时需要访问多个物理位置来检索完整的数据行(参考)。如果一条记录在一页中,查询就会很快,也没有IO去磁盘查询,因为页数据是在缓冲池(Buffer pool)中。但是行溢出可以提高表的存储效率和性能,因为它允许存储引擎只存储数据的一部分,而不是整个数据。


http://www.mrgr.cn/news/47743.html

相关文章:

  • 基于 gitlab-runner 实现调度GPU的资源
  • C#语言的数据库编程
  • Openssl1.1.1s rpm包构建与升级
  • Spring配置文件中:密码明文改为密文处理方式(通用方法)
  • 前端批量下载文件
  • Oracle job(定时任务)
  • 扩散模型代码实战:无条件图像生成扩散模型
  • 零基础也可以搞懂负载均衡怎么配置!
  • 怎样批量删除大量的QQ邮件?
  • 《大模型应用开发极简入门》学习成为善用 AI 的人!看完懂得90%的大模型!{含pdf版电子书}_大模型应用开发极简入门 pdf
  • 精准控制外发文档的打开次数、时间,过期自动删除无法打开,赶紧收藏
  • MLCC贴片电容不同材质区别:【及电容工作原理】
  • 康达新材: 以CRM丰富数字化转型助推业务全面升级
  • 国企最爱的校招大学院校和专业,都有哪些呢?盘点一下
  • 【4G低功耗摄像头快速启动抓拍形式 秒级别唤醒方案功耗超低】
  • 2024选购文件加密软件的避坑指南 |如何选择好用的文档加密软件
  • tp框架网络请求
  • YOLOv11改进策略【注意力机制篇】| 引入SimAM注意力模块(一个简单的,无参数的卷积神经网络注意模块)
  • vue3--通用组件 popup 封装
  • 猫头虎分享:Python库 Django 的简介、安装、用法详解入门教程
  • 如何用源码快速搭建属于你的外卖系统?
  • 推进大模型在数字政府中的应用
  • 通信接入技术
  • Windows下MYSQL8.0如何恢复root权限
  • iPhone 16的最佳充电搭子——慧能泰PD快充芯片HUSB339D
  • 独家重磅发布《2024银发流量全景洞察报告》