性能原因
-
text字段通常以外部存储方式保存,而不是像固定长度或可变长度字段那样以行内存储的方式。通过观察行记录的格式,可以观察到text类型的数据使用一个指针专门指向特定的存储空间的。这意味着读取带text的数据需要额外的磁盘IO。
-
text类型的数据可能很大,无法完全加载到内存中,就更需要依赖于频繁的磁盘IO来读取和更新。
-
而且由于text类型数据本身可能就很庞大,本就存储和检索的速度很慢。
Variable-length field length list | NULL | record_header | col_value | text_value | |
---|---|---|---|---|---|
变长字段长度列表 | null值列表 | 隐藏字段 | 记录头信息- | 列数据 | Text列指针数据 |
注:隐藏字段包括 row_id、trx_id、roll_pointer
索引限制
由于索引有长度限制,text类型的数据可能无法加索引,或者只能使用前缀索引。
表空间碎片
由于text类型的数据的长度是可变的,会有和varchar一样的问题,由于存储在数据页中,频繁的更新或删除可能导致产生较多的空间碎片,造成磁盘空间浪费和使得查询性能下降。
那抹如何解决要存储较大类型的数据呢?
-
针对一些不经常读取的数据或者性能要求不高的场合,使用text类型是可以的。所以可以将这些数据垂直分库或分表提取出来而不影响正常业务的查询。
-
但如果对于需要经常读取的场合,则就需要考虑借用其他专门的文件系统来存储,而在我们的表中就使用文件系统的路径或引用。
-
例如使用es存储,在MySQL中,一般log表会存储text类型保存request或response类的数据,用于接口调用失败时去手动排查问题,使用频繁的很低。可以考虑写入本地log file,通过filebeat抽取到es中,按天索引,根据数据保留策略进行清理。
-
或者使用对象存储,有些业务场景表用到TEXT,BLOB类型,存储的一些图片信息,比如商品的图片,更新频率比较低,可以考虑使用对象存储,例如阿里云的OSS,AWS的S3都可以,能够方便且高效的实现这类需求。
-
java - 为什么阿里巴巴不建议MySQL使用Text类型? - 我们一起进大厂 - SegmentFault 思否可以参考这个例子,解决如何存储log日志,log日志存在MySQL中直接慢查询了。