Crunchy Data Blog

7 篇内容

工程实践Crunchy Data Blog

Hybrid Search Patterns with Postgres and pgvector

文章系统探讨了在PostgreSQL和pgvector中实现混合搜索(向量相似度加标量过滤)的工程模式。首先阐述了pgvector迭代索引扫描如何平衡召回与性能,然后分析了向量优先和标量优先两条路径各自的适用场景与局限。作者进一步提供了三种实用工作区:为低基数过滤构建部分HNSW索引;通过过采样再过滤应对高基数或临时过滤器;以及利用缓存加速重复查询。文中给出了过采样的估算公式、查询计划诊断方法以及各方案的决策指南,并强调了每种模式在召回率、性能和维护成本之间的权衡。

推荐收录,因为本文是针对Postgres+pgvector混合搜索问题的实战指南,从问题根源到四种解决方案给出了完整的权衡分析、代码示例和调优公式,远超简单教程。适合正在构建带标量过滤的向量搜索系统的工程师,文中部分索引、过采样和缓存等模式可直接应用于生产环境,决策树和EXPLAIN诊断方法具有跨场景的可迁移价值。

技术文章Crunchy Data Blog

Postgres 19 Compression: from pglz to LZ4

Postgres 19计划将默认TOAST压缩算法从pglz切换为LZ4。本文追溯了从Postgres 7.0引入lztext到7.1实现TOAST与pglz的历史,解释了pglz设计的取舍:速度优先、极小内存占用、快速终止和零外部依赖。然后对比了LZ4的优势:更快的压缩速度(测试中提速约8倍)、更大的滑动窗口带来更好的压缩率,并保留了快速终止特性。文章详细说明了变长类型的varlena格式、EXTENDED/PLAIN/EXTERNAL/MAIN四种存储策略,以及写入时的压缩决策树:行大小超过约2KB阈值时,依次压缩前列大对象或移入TOAST表。此外,还介绍了B树索引中机会主义压缩的机制:当键值超过510字节时尝试压缩,并举例说明可压缩与不可压缩数据对索引的影响。整体内容既包含机制解析也包含实践测试,展示了Postgres团队在压缩演进上的谨慎策略。边界在于测试非科学化,且未深入LZ4算法内部细节。

本文系统梳理了Postgres压缩框架的历史、原理与决策路径,并结合代码示例和对比数据说明LZ4替代pglz的收益。适合需要理解Postgres存储优化、TOAST机制或索引限制的DBA与开发者,可迁移的价值在于掌握如何诊断压缩效果、选择存储策略以及评估算法升级对性能的影响。内容详实且有长期参考价值。

工程实践Crunchy Data Blog

British Columbia, Time Zones, and Postgres

文章以不列颠哥伦比亚省时区规则变更为例,讨论了 PostgreSQL 中时间存储的核心陷阱:把未来的“本地意图”仅用 timestamptz 保存,会因 tzdata 更新而在查询时还原出错误的本地时间。作者进一步提出双列模式,将 local_time 和 timezone_name 作为事实源,再用触发器计算并维护 starts_at_utc,以同时满足本地语义、UTC 索引与约束检查的需求。文中还说明了这种方案的适用边界、tzdata 变更后的重算策略,以及 RFC 9557 目前并不能解决这类未来本地时间问题。

推荐收录,因为文章围绕真实的时区规则变更给出了可直接迁移到数据库设计中的方案,不只是泛泛讲时间处理。它对预约、日程、法务截止时间等需要保留未来本地意图的系统尤其有参考价值,也明确提醒了哪些场景仍应继续使用 plain timestamptz。

工程实践Crunchy Data Blog

Postgres Serials Should be BIGINT (and How to Migrate)

这篇文章讨论了 Postgres 中自增主键从 SERIAL/INT 升级到 BIGINT 的必要性,核心理由是 INT 只有约 21 亿上限,而 BIGINT 基本不会溢出。作者进一步说明 BIGINT 在很多行布局下并不比 INT 更占空间,因为 PostgreSQL 的行对齐和填充会抵消所谓的 4 字节节省,因此用 BIGINT 的长期成本通常很低。文章还对比了 UUID 的适用场景,认为跨系统或需要公开暴露 ID 的场景可以选 UUID,但纯数据库序列号未必需要放弃整数。随后给出了一套可在线执行的迁移方案:新增 BIGINT 列、触发器同步、分批回填、定期 VACUUM、并发建唯一索引、处理外键引用表,再在一个短事务里完成 atomic swap。文中也强调了边界条件:需要预留短暂排它锁、先在非生产环境验证批次大小和回填策略,并确保序列、外键和主键约束在切换后都能正确接管。

推荐收录,因为文章直接给出了从 INT 到 BIGINT 的完整 PostgreSQL 迁移链路,包含分批回填、NOT VALID 外键、并发建索引和原子切换等可复用证据。适合负责数据库演进、线上改表或容量规划的后端/DBA 读者,主要价值是把一次高风险 schema 变更拆成可验证的操作步骤。

工程实践Crunchy Data Blog

Postgres 18 New Default for Data Checksums and How to Deal with Upgrades

文章介绍了 Postgres 18 将数据校验和(data checksums)设为 initdb 的默认开启项,强调其核心价值是及早发现磁盘页的静默损坏。作者先解释校验和如何在写入数据页时生成、存入页头,并在读取时重新计算比对,从而把原本难以察觉的数据腐败转化为可报警错误。随后文章说明这一默认变化对新建集群是纯收益,但会影响使用 pg_upgrade 的大版本升级,因为新旧集群的校验和开关必须一致。文中给出两条应对路径:升级时可用 --no-data-checksums 保持兼容,或提前用 pg_checksums 为现有集群补开校验和,但后者通常需要停机或通过副本切换来降低影响。整体适用于自建 PostgreSQL 运维、升级规划和备份完整性管理场景。

文章直接给出 Postgres 18 默认行为变化、pg_upgrade 兼容条件和 pg_checksums 处理方案,证据明确且可操作性强。适合数据库运维、平台工程和升级规划读者,尤其对自建集群的完整性保障与停机权衡有长期参考价值。

技术文章Crunchy Data Blog

PostGIS Performance: Simplification

这篇文章围绕 PostGIS 中“几何简化”展开,比较了多种常见方法在点数压缩、形状保真和有效性上的差异。作者先用 ST_Letters、ST_Segmentize 和 ST_RemoveRepeatedPoints 构造出可观察的测试图形,再依次展示 ST_Simplify(Douglas-Peucker)、ST_SimplifyVW(Visvalingam-Whyatt)、ST_SnapToGrid 与 ST_ReducePrecision 的效果。文章指出,Douglas-Peucker 更偏向折线压缩,VW 在多边形形状保留上通常更好,而简单网格吸附虽能统一精度却容易产生无效多边形。相较之下,ST_ReducePrecision 在固定精度与几何有效性之间提供了更稳妥的折中。最后还补充了 PostGIS 3.6 新增的覆盖面处理能力:先用 ST_CoverageClean 清理共享边界,再用 ST_CoverageSimplify 对相邻面集合整体简化,适用于需要边界一致性的专题图或覆盖数据。

文章直接比较了多种 PostGIS 简化函数的输出差异、有效性风险和适用场景,不是泛泛介绍 API。对做空间数据处理、地图渲染或数据库性能优化的读者很有参考价值,尤其适合需要在精度、合法性和边界一致性之间做取舍的工程场景。

技术文章Crunchy Data Blog

How to Read Postgres EXPLAIN: A Guide to Scan Types

这篇文章以 Postgres 的 EXPLAIN 输出为切入点,系统讲解了常见扫描类型及其适用场景,帮助读者从执行计划中判断查询为何快或慢。文章依次解释了顺序扫描、索引扫描、位图索引扫描与位图堆扫描、并行顺序扫描、并行索引扫描以及索引仅扫描,并配合真实的 EXPLAIN ANALYZE 示例展示各自的计划形态和指标。作者不仅说明了这些扫描方式的工作机制,还强调了优化器的选择逻辑,例如小表、返回比例较高或需要随机访问过多时,顺序扫描可能优于索引扫描。对于索引仅扫描,文章进一步讨论了覆盖索引带来的收益,以及写放大、索引体积和适用列数等边界条件。整体上,这是面向 PostgreSQL 性能排查与执行计划阅读的实用入门,但内容仍以常见扫描类型为主,未深入展开代价模型或更复杂的连接/排序计划。

文章直接给出了多种 EXPLAIN 扫描节点的真实输出和判读方法,适合做 PostgreSQL 性能排查、SQL 优化和执行计划入门参考。它的可迁移价值在于帮助读者建立“选择哪种扫描方式、为什么会选它”的心智模型,但内容主要覆盖基础扫描类型,深层优化仍需结合具体工作负载。