mysql如何解决执行SQL时的Text/Blob字段溢出页问题_分析行溢出存储

梦强小哥_1733

梦强小哥_1733

2026-04-25

535人浏览

原创

TEXT/BLOB字段在DYNAMIC/COMPRESSED行格式下,内容超约8000字节时会自动存入溢出页,仅留20字节指针在主记录中,导致额外I/O、缓存效率下降和查询变慢;确认需结合行格式与实际长度判断,而非仅看字段类型。

mysql如何解决执行sql时的text/blob字段溢出页问题_分析行溢出存储

MySQL 中 TEXT/BLOB 字段触发行溢出页,不是 bug,而是 InnoDB 在 ROW_FORMAT=DYNAMIC 或 COMPRESSED 下的正常行为。它本身不报错,但会悄悄把字段主体挪到独立溢出页,导致查询变慢、缓存效率下降——关键在于你是否意识到这个 I/O 开销正在发生。

怎么确认某条记录真的用了溢出页

不能只看字段类型是 TEXT 就断定用了溢出页;得看实际内容长度和当前行格式。最直接的办法是查 INFORMATION_SCHEMA.INNODB_SYS_TABLES 和 INFORMATION_SCHEMA.INNODB_SYS_COLUMNS,但更实用的是用 SHOW CREATE TABLE 确认行格式,并结合内容长度做判断:

  • SHOW VARIABLES LIKE 'innodb_default_row_format'; —— 多数 MySQL 5.7+ 返回 DYNAMIC
  • SELECT LENGTH(content) FROM article WHERE id = 1; —— 如果结果 > 8000 字节,且表是 DYNAMIC 格式,基本就进了溢出页
  • 执行 SELECT * FROM article 时用 EXPLAIN FORMAT=JSON 查看是否出现 "using_temporary_table": true 或明显延迟,是间接信号

为什么 SELECT * 会突然变慢,而只查几个字段就快

因为 SELECT * 强制读取所有列,包括被移到溢出页的 content 字段,InnoDB 必须额外发起一次(或多次)随机磁盘 I/O 去加载那些溢出页;而 SELECT id, title, summary 这类不含大字段的查询,整行数据能塞进主数据页,一次读完。

  • 溢出页地址只存 20 字节指针在主记录里,不读就不触发加载
  • Buffer Pool 缓存的是页,不是字段;溢出页分散,缓存命中率天然低
  • 全表扫描时,每行都可能触发一次额外 I/O,QPS 直接腰斩很常见

TEXT 改成 VARCHAR 能避免溢出页吗

不能,反而可能让问题更隐蔽甚至失败。VARCHAR 的最大理论长度受整行限制(65535 字节),还要扣除其他字段、长度头、NULL 标识等开销。一旦定义 VARCHAR(60000),建表时大概率被 MySQL 自动转成 TEXT,并伴随 warning:

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
Warning | 1246 | Converting column `content` from VARCHAR to TEXT
  • VARCHAR 只有在内容短(比如
  • 想靠加长 VARCHAR 避免溢出页,等于在撞 InnoDB 行大小硬限制,大概率失败或被静默转换
  • 真要控制溢出,优先考虑业务层截断、压缩、或拆分存储(如正文 + 摘要 + 标签三张表)

哪些操作会意外放大溢出页影响

不是所有读都会触发溢出页加载,但这些操作会:

  • ORDER BY 或 GROUP BY 涉及 TEXT/BLOB 字段 —— InnoDB 可能需要完整值排序,强制加载溢出页
  • WHERE content LIKE '%xxx%' —— 即使没索引,优化器也可能决定全扫+逐行加载溢出内容
  • 使用 mysqldump 导出整表 —— 默认 SELECT *,每行都拉溢出页,导出速度骤降
  • 开启 innodb_file_per_table=OFF 时,溢出页混在系统表空间,碎片更难清理

最容易被忽略的是:溢出页一旦生成,不会因后续更新变短而自动回收回主记录——哪怕你把 content UPDATE 成空字符串,那 20 字节指针还在,溢出页仍占磁盘空间,直到执行 OPTIMIZE TABLE 或重建表。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
mysql修改数据表名
mysql修改数据表名

MySQL修改数据表:1、首先查看数据库中所有的表,代码为:‘SHOW TABLES;’;2、修改表名,代码为:‘ALTER TABLE 旧表名 RENAME [TO] 新表名;’。php中文网还提供MySQL的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.20

2393

6

MySQL创建存储过程
MySQL创建存储过程

存储程序可以分为存储过程和函数,MySQL中创建存储过程和函数使用的语句分别为CREATE PROCEDURE和CREATE FUNCTION。使用CALL语句调用存储过程智能用输出变量返回值。函数可以从语句外调用(通过引用函数名),也能返回标量值。存储过程也可以调用其他存储过程。php中文网还提供MySQL创建存储过程的相关下载、相关课程等内容,供大家免费下载使用。

2023.06.21

1459

5

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

855

5

mysql密码忘了怎么查看
mysql密码忘了怎么查看

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql密码忘了怎么办呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.19

3372

5

mysql创建数据库
mysql创建数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS 应用软件之一。那么mysql怎么创建数据库呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.25

5788

4

mysql默认事务隔离级别
mysql默认事务隔离级别

MySQL是一种广泛使用的关系型数据库管理系统,它支持事务处理。事务是一组数据库操作,它们作为一个逻辑单元被一起执行。为了保证事务的一致性和隔离性,MySQL提供了不同的事务隔离级别。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.08

1259

3

sqlserver和mysql区别
sqlserver和mysql区别

SQL Server和MySQL是两种广泛使用的关系型数据库管理系统。它们具有相似的功能和用途,但在某些方面存在一些显著的区别。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.11

6051

4

mysql忘记密码
mysql忘记密码

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。那么忘记mysql密码我们该怎么解决呢?php中文网给大家带来了相关的教程以及其他关于mysql的文章,欢迎大家前来学习阅读。

2023.08.14

5242

7

mysql事务隔离级别
mysql事务隔离级别

mysql规范中定义了四种事务隔离级别,不同的隔离级别对事务的处理有所不同。本专题为大家提供mysql事务隔离级别相关的文章内容,大家可以免费体验。

2023.08.16

7034

11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 193人学习