伊丽莎白·加勒特·克里斯滕森:Postgres TOAST:自切片面包以来最伟大的发明?

伊丽莎白·加勒特·克里斯滕森:Postgres TOAST:自切片面包以来最伟大的发明?

💡 原文英文,约1100词,阅读约需4分钟。
📝

内容提要

Postgres使用TOAST将大于8kb的数据分割成较小的块进行存储,TOAST可能会影响查询性能,并且由Postgres自动完成。TOASTed数据存储在单独的表中,并且可以进行压缩。TOASTed数据通常对查询响应较慢。为了实现高效的存储和检索,重要考虑数据类型设置和数据建模的改变。

🔎

延伸解读

TOAST 的自动机制与存储选项

TOAST 是 Postgres 自动处理大数据的机制,无需手动设置。当行超过 2KB 时,Postgres 会将数据分割成 2KB 的块并存储在单独的 TOAST 表中。数据类型的存储属性(如 PLAIN、EXTENDED、EXTERNAL、MAIN)决定了是否启用 TOAST 和压缩。例如,TEXT 和 JSONB 默认使用 EXTENDED(压缩+TOAST),而 NUMERIC 使用 MAIN(仅压缩)。了解这些设置有助于优化存储和查询性能。

TOAST 对查询性能的影响

TOAST 虽然能存储大数据,但可能降低查询性能。TOASTed 数据存储在单独的表中,查询时需要额外查找和组装,增加复杂性。更新 TOASTed 行的单个列时,由于 MVCC 机制,所有受影响的页面都需要更新,可能导致写放大和死元组积累。频繁访问的数据应避免 TOAST,尤其是经常更新的 JSON 字段或用于全文搜索的文本。

数据建模与 TOAST 规避策略

为避免 TOAST 带来的性能问题,建议对频繁查询的大数据采用传统列结构进行拆分。例如,将 JSON 中的常用字段提取为独立列,或使用 ST_Subdivide() 分割空间数据。对于已压缩的自定义数据类型,可设置存储属性为 EXTERNAL 以避免重复压缩。定期检查 TOAST 表的使用情况(通过 pg_class 查询),有助于识别哪些数据被 TOAST 并评估其必要性。

❓

Q&A

Postgres的TOAST是什么?它有什么作用?

TOAST是The Oversized Attribute Storage Technique的缩写,是Postgres用于存储大于8KB页大小的数据的机制。它将大块数据分割成较小的块(每块2KB)存储在单独的TOAST表中,并自动建立索引以加快查找。TOAST自动进行,无需手动设置。

TOAST对查询性能有什么影响?

TOASTed数据通常查询响应较慢,因为需要从TOAST表中检索并重组数据。此外,更新TOASTed行的单个列时,必须更新所有受影响的页面,可能导致写放大和性能问题。频繁访问的数据不应使用TOAST,否则会影响效率。

Postgres中数据类型的存储选项有哪些?它们如何影响TOAST和压缩?

存储选项包括:PLAIN(不压缩、不TOAST,用于小数据类型如INTEGER)、EXTENDED(压缩且TOAST,TEXT/JSON等默认)、EXTERNAL(不压缩但TOAST,用于已压缩数据)、MAIN(压缩但不TOAST,用于NUMERIC)。这些选项影响数据是否被TOAST和压缩。

如何查询数据库中哪些表有TOAST表以及它们的大小?

可以使用以下查询:SELECT c.relname AS source_table_name, c.relpages AS source_table_number_of_pages, c.reltuples AS source_table_number_of_tuples, c.reltoastrelid AS toast_table_oid, t.relname AS toast_table_name, t.relpages AS toast_table_number_of_pages, t.reltuples AS toast_table_number_of_tuples FROM pg_class c JOIN pg_class t ON c.reltoastrelid = t.oid WHERE t.relpages > 0;

在什么情况下应该避免使用TOAST?如何优化?

频繁访问和查询的数据应避免TOAST,因为TOAST会增加查询延迟。优化方法包括:使用传统列结构代替大文本或JSON;对于空间数据,使用ST_Subdivide()分割大型几何对象;避免对经常访问的数据进行压缩(如全文搜索的文本)。

Postgres的页面大小是多少?TOAST段的大小是多少?

Postgres的页面大小为8KB,不可配置。TOAST段的大小为2KB,因此每个8KB页面大约包含4个TOAST段。

🏷️

标签

➡️

继续阅读