" fdw_redis"扫描所有Redis记录而不是单个查询

时间:2018-02-02 14:13:47

标签: postgresql redis postgresql-9.6

我在通过Redis-> Postgresql 9.6

转换信息时遇到问题

我在hiredis上使用扩展名fdw_redis,我创建了FOREIGN TABLE redis_db0_ch。

当我进行简单查询时

select "key", value from redis_db0_ch where "key"='Ch_152';

使用" cli-redis monitor"我看到它没关系:单一资格Redis for 1 sql-query

  

" ZRANGE" " Ch_152" " 0" " -1"

但是当我使用输入参数将sql-query包装到Function中时:

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-query成为:

select * from "SMSCEngine".f_get_redis_test(152);

结果" cli-redis监视器"被压倒了:5次没关系,但随后开始扫描所有redis记录,忽略了我的过滤器(其中"键" =' Ch _')

  

" ZRANGE" " Ch_152" " 0" " -1" // 5次

     

" SCAN" " 0" " MATCH" "章_ *" " COUNT" &#34 1000" //来自6次

结果 - 降低了性能。 我想这是postgres或扩展中的优化方法。 我该如何解决?

1 个答案:

答案 0 :(得分:0)

这看起来像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" = $1'
    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$