"fdw_redis" 扫描所有 Redis 记录而不是单个查询
"fdw_redis" scan all Redis records instead single query
我在通过 Redis->Postgresql 9.6
转换信息时遇到问题
我将扩展程序 fdw_redis 与 hiredis 一起使用,我创建了 FOREIGN TABLE redis_db0_ch.
当我进行简单查询时
select "key", value from redis_db0_ch where "key"='Ch_152';
使用“cli-redis monitor”我看到它没问题:对 Redis 的单一质量为 1 sql-query
"ZRANGE" "Ch_152" "0" "-1"
但是当我将 sql-query 包装到具有输入参数的函数中时:
CREATE OR REPLACE FUNCTION "SMSCEngine".f_get_redis_test(input_param integer)
RETURNS TABLE(_key text, _value text)
LANGUAGE plpgsql
AS $function$
begin
return query
select "key", value from redis_db0_ch where "key"='Ch_' || input_param;
end;
$function$
sql-查询变为:
select * from "SMSCEngine".f_get_redis_test(152);
“cli-redis monitor”的结果被淹没了:5 次没问题,但随后它开始扫描所有 redis 记录,忽略了我的过滤器(其中“key”='Ch_')
"ZRANGE" "Ch_152" "0" "-1" //5 times
"SCAN" "0" "MATCH" "Ch_*" "COUNT" "1000" //from 6 times
因此 - 性能下降。
我想这是postgres或扩展中的优化方法。
我该如何解决?
这看起来像 PL/pgSQL plan caching 的结果。你是对的,它应该是一种优化技术,但正如你所看到的,它偶尔会做出一些非常有问题的决定。
通常,您可以通过 运行 通过 EXECUTE
查询来抑制此行为,这将强制 PL/pgSQL 每次都重新计划它:
CREATE OR REPLACE FUNCTION "SMSCEngine".f_get_redis_test(input_param integer)
RETURNS TABLE(_key text, _value text)
LANGUAGE plpgsql
AS $function$
begin
return query
execute 'select "key", value from redis_db0_ch where "key" = '
using 'Ch_' || input_param;
end;
$function$
但是,如果您的函数只是一个查询,则可能根本不需要 PL/pgSQL;你可以写成LANGUAGE sql
,据我所知,没有这个问题:
CREATE OR REPLACE FUNCTION "SMSCEngine".f_get_redis_test(input_param integer)
RETURNS TABLE(_key text, _value text)
LANGUAGE sql
AS $function$
select "key", value from redis_db0_ch where "key" = 'Ch_' || input_param
$function$
我在通过 Redis->Postgresql 9.6
转换信息时遇到问题我将扩展程序 fdw_redis 与 hiredis 一起使用,我创建了 FOREIGN TABLE redis_db0_ch.
当我进行简单查询时
select "key", value from redis_db0_ch where "key"='Ch_152';
使用“cli-redis monitor”我看到它没问题:对 Redis 的单一质量为 1 sql-query
"ZRANGE" "Ch_152" "0" "-1"
但是当我将 sql-query 包装到具有输入参数的函数中时:
CREATE OR REPLACE FUNCTION "SMSCEngine".f_get_redis_test(input_param integer)
RETURNS TABLE(_key text, _value text)
LANGUAGE plpgsql
AS $function$
begin
return query
select "key", value from redis_db0_ch where "key"='Ch_' || input_param;
end;
$function$
sql-查询变为:
select * from "SMSCEngine".f_get_redis_test(152);
“cli-redis monitor”的结果被淹没了:5 次没问题,但随后它开始扫描所有 redis 记录,忽略了我的过滤器(其中“key”='Ch_')
"ZRANGE" "Ch_152" "0" "-1" //5 times
"SCAN" "0" "MATCH" "Ch_*" "COUNT" "1000" //from 6 times
因此 - 性能下降。 我想这是postgres或扩展中的优化方法。 我该如何解决?
这看起来像 PL/pgSQL plan caching 的结果。你是对的,它应该是一种优化技术,但正如你所看到的,它偶尔会做出一些非常有问题的决定。
通常,您可以通过 运行 通过 EXECUTE
查询来抑制此行为,这将强制 PL/pgSQL 每次都重新计划它:
CREATE OR REPLACE FUNCTION "SMSCEngine".f_get_redis_test(input_param integer)
RETURNS TABLE(_key text, _value text)
LANGUAGE plpgsql
AS $function$
begin
return query
execute 'select "key", value from redis_db0_ch where "key" = '
using 'Ch_' || input_param;
end;
$function$
但是,如果您的函数只是一个查询,则可能根本不需要 PL/pgSQL;你可以写成LANGUAGE sql
,据我所知,没有这个问题:
CREATE OR REPLACE FUNCTION "SMSCEngine".f_get_redis_test(input_param integer)
RETURNS TABLE(_key text, _value text)
LANGUAGE sql
AS $function$
select "key", value from redis_db0_ch where "key" = 'Ch_' || input_param
$function$