使用redis_fdw在PostgreSQL中执行UPDATE和DELETE查询的问题
Redis FDW批量更新/删除问题及解决方案
1. redis_fdw对UPDATE ... FROM和DELETE ... USING的支持情况
redis_fdw对这类包含JOIN子句的复杂UPDATE/DELETE语句支持有限,尤其是在1.x版本系列中。它的外部表更新、删除逻辑仅适配简单单表操作,无法正确解析带有FROM/USING子查询的语句,核心原因是其查询规划器适配能力不足,无法生成有效的执行路径。
2. 批量更新和删除的替代方案
批量更新
- PL/pgSQL循环执行单条更新:遍历子查询结果,逐个执行简单UPDATE语句,适合中小数据量:
DECLARE rec RECORD; BEGIN FOR rec IN SELECT key, agg(...) AS val FROM mytable INNER JOIN ... GROUP BY ... LOOP UPDATE redis_db7 SET val = rec.val WHERE key = rec.key; END LOOP; END;
- 直接调用Redis批量命令:利用redis_fdw提供的
redis_exec函数(若版本支持),拼接Redis的MSET命令批量写入,性能更优:
-- 先将聚合结果转为Redis MSET所需的键值对列表,再执行 SELECT redis_exec('MSET', (SELECT string_agg(concat_ws(' ', key, val), ', ') FROM (SELECT key, agg(...) AS val FROM mytable INNER JOIN ... GROUP BY ...) t) );
批量删除
- PL/pgSQL循环执行单条删除:
DECLARE rec RECORD; BEGIN FOR rec IN SELECT key FROM mytable INNER JOIN ... GROUP BY ... LOOP DELETE FROM redis_db7 WHERE key = rec.key; END LOOP; END;
- 直接调用Redis DEL命令:拼接需要删除的键列表,执行批量删除:
SELECT redis_exec('DEL', (SELECT string_agg(key, ', ') FROM (SELECT key FROM mytable INNER JOIN ... GROUP BY ...) t) );
注:如果数据量极大,建议分批次处理(比如每次取1000条),避免单次操作耗时过长。
3. [XX000] ERROR: could not find pathkey item to sort.报错原因
- PostgreSQL查询规划器在为外部表生成执行计划时,无法找到匹配的排序键来处理子查询(含GROUP BY/JOIN)与外部表的关联逻辑。
- redis_fdw未为外部表提供足够的统计信息或排序支持,导致规划器无法推导有效的排序路径。
- 旧版本redis_fdw存在规划器适配缺陷,无法正确解析复杂查询的执行计划逻辑,进而触发该错误。
内容的提问来源于stack exchange,提问作者Morteza Seydi
相关产品推荐
相关产品推荐

