内容提要
pg-jev 是 PostgreSQL 扩展,可用自然语言条件逐行判断数据,无需向量索引或 embedding。jev() 作为布尔函数可融入 SQL,按批调用 API,默认每批 20 行,以兼顾准确率与成本。结果缓存在会话中,重复查询仅需约 50 毫秒。但使用需超级用户权限和 plpython3u,托管服务不支持。查询 2000 行约花费 1.2 美分、耗时 3.5 秒。
延伸解读
与向量检索的本质区别
pg-jev 不依赖向量索引或 embedding,而是将每一行数据直接发送给 Jev 模型进行语义判断。这与 pgvector 等方案形成鲜明对比:后者需要预先计算 embedding 并建立近似最近邻索引,而 pg-jev 完全跳过了索引构建环节。对于“名字听起来像欧洲人”这类无法用传统索引表达的语义条件,pg-jev 提供了直接可行的路径,但代价是逐行调用模型,成本随数据量线性增长。
成本与准确率的权衡
jev 默认每批 20 行,这是准确率与成本之间的平衡点。实验显示,批次在 1 到 20 行时准确率 100%,40 行时降至 92%-98%,80 行时仅 77%-94%。同时,批次越小,每行消耗的输入 Token 越多:批次为 1 时每行 435 Token,批次为 20 时约 175 Token。因此,调大或调小批次都会影响开销和判断质量,用户需根据实际场景谨慎调整。
部署限制与适用场景
pg-jev 依赖 plpython3u 扩展,该扩展被 PostgreSQL 标记为“不可信”,因此只有超级用户才能安装。这意味着 Supabase、Neon、RDS 等托管服务无法使用,因为它们不提供超级用户权限。实际可用的场景仅限于自管服务器或 Docker 环境。此外,连接池会放大冷启动成本:每个新连接首次请求平均多花 1.5 秒,且缓存随连接独立,连接池越大,重复查询的缓存命中率越低。
使用注意事项与防烧钱设置
jev 提供 jev_stats() 函数监控请求次数、Token 消耗和成本。为防止意外高额账单,可启用 jev.max_rows_per_statement 和 jev.max_chars_per_statement(默认关闭),限制单条语句发送的行数或字符数。另外,避免在子查询或 CTE 中使用 jev,因为匿名 record 类型无法预读,会导致逐行调用且无批处理折扣。将 jev 用于基础表或视图,才能利用其按 TID 范围扫描的优化。
Q&A
pg-jev 是什么?它和向量检索方案有什么不同?
pg-jev 是一个 PostgreSQL 扩展,允许用自然语言条件逐行判断数据。它不需要向量索引或 embedding,而是将每行数据打包发送给 TypeSafe 的 Jev 模型,模型返回 0 到 1 的概率值,数据库根据概率决定是否保留该行。与 PostgresML、pgvector 等方案不同,它不建索引、不读表结构、不让模型生成 SQL,而是直接逐行判断。
pg-jev 的 jev() 函数怎么用?能和其他 SQL 条件组合吗?
jev() 是一个普通的布尔函数,可以像其他条件一样用在 WHERE、JOIN、GROUP BY、ORDER BY 等子句中。例如:SELECT * FROM people WHERE jev(people, 'the name is European')。它返回 true 或 false,因此可以和 AND age > 40 等条件组合,数据库优化器会先执行便宜的条件,再调用模型判断。
pg-jev 的批处理大小为什么默认是 20 行?
jev 默认每批发送 20 行数据给 API,以平衡准确率和成本。批次越大,每行分摊的请求固定开销越少,但模型在长数组中按位置找行的准确率会下降。实验显示:批次 1-20 行准确率 100%,40 行降至 92%-98%,80 行仅 77%-94%。20 行是准确率和成本的最优平衡点。
pg-jev 的缓存机制是怎样的?重复查询能省多少钱?
jev 将每行的判断结果缓存在当前数据库会话的内存中。第一次查询 2000 行花费约 1.2 美分和 3.5 秒,第二次相同条件查询只需约 50 毫秒,因为答案已在缓存中,无需调用 API。修改阈值(如 SET jev.threshold = 0.7)或按概率排序也无需重新调用 API,直接使用缓存概率值即可。
pg-jev 对安装环境有什么要求?托管数据库能用吗?
pg-jev 依赖 PostgreSQL 的 plpython3u 扩展,该扩展被标记为“不可信语言”,因此只有 PostgreSQL 超级用户才能安装。这意味着你必须在自己的服务器或 Docker 容器中运行 PostgreSQL,并拥有超级用户权限。Supabase、Neon、RDS 等托管服务不提供超级用户权限,也不支持 plpython3u,因此无法运行 pg-jev。
使用 pg-jev 时如何防止 API 费用失控?
jev 提供了两个设置:jev.max_rows_per_statement 和 jev.max_chars_per_statement,默认均为 0(关闭)。开启并设置阈值(如 10000 行和 1000000 字符)后,任何 SQL 语句如果会向 API 发送超过限制的数据,PostgreSQL 会直接中断该语句。这是在共享数据库上防止意外高额账单的唯一手段。
pg-jev 在冷连接和热连接下的性能差异有多大?
冷连接(新建连接)的第一次请求需要额外的 TLS 握手和服务端初始化,实测每条新连接首次请求平均多花 1.5 秒。例如 2000 行全表判断在冷连接下约 3.5 秒,而在热连接(连接已建立)下可降至约 0.6 秒。连接空闲超过 600 秒会被回收,下次请求重新冷启动。