【问题标题】:"fdw_redis" scan all Redis records instead single query"fdw_redis" 扫描所有 Redis 记录而不是单个查询
【发布时间】:2018-02-03 06:13:47
【问题描述】:

我在通过 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”我看到没问题:single qual to 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 monitor”中的结果被淹没:5次没问题,但随后它开始扫描所有redis记录,忽略我的过滤器(其中“key”='Ch_')

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

"SCAN" "0" "MATCH" "Ch_*" "COUNT" "1000" //从 6 次开始

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

【问题讨论】:

    标签: postgresql redis postgresql-9.6


    【解决方案1】:

    这看起来像是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$
    

    【讨论】:

      猜你喜欢
      • 2019-05-26
      • 1970-01-01
      • 2018-05-05
      • 1970-01-01
      • 2022-12-05
      • 2017-09-10
      • 1970-01-01
      • 2020-06-11
      • 1970-01-01
      相关资源
      最近更新 更多