【问题标题】:Parsing through a QUERY PLAN to return specific results通过 QUERY PLAN 解析返回特定结果
【发布时间】:2021-11-30 01:36:00
【问题描述】:

我正在尝试创建一个函数来估计给定超表中的行数。

select * from items where id = 'Xa4511' and "timestamp" >= date_trunc('day', now());
Custom Scan (ChunkAppend) on items    (cost=0.42..150.97 rows=76 width=160)
  Chunks excluded during startup: 75
  ->  Index Scan using _hyper_2_2128_chunk_items_id_timestamp_idx on _hyper_2_2128_chunk  (cost=0.42..2.44 rows=1 width=136)
        Index Cond: (((id)::text = 'Xa4511'::text) AND ("timestamp" >= date_trunc('day'::text, now())))

我可以在Custom Scan (ChunkAppend) on items (cost=0.42..150.97 rows=76 width=160)得到76

但是对于这个特定的表,更愿意循环遍历这些扫描中的每一个: -> Index Scan using _hyper_2_2128_chunk_items_id_timestamp_idx on _hyper_2_2128_chunk (cost=0.42..2.44 rows=1 width=136) 并拉出每个行,因为它更准确一些。但是,我使用的查询总是返回 null。

例如:

Custom Scan (ChunkAppend) on items (cost=0.29..4751.10 rows=51440 width=196)
  Chunks excluded during startup: 54
  ->  Index Scan using _hyper_5_2121_chunk_items_id_timestamp_idx on _hyper_5_2121_chunk  (cost=0.42..1722.80 rows=19017 width=196)
        Index Cond: (((id)::text = 'xb1a'::text) AND ("timestamp" >= date_trunc('month'::text, now())))
  ->  Index Scan using _hyper_5_2097_chunk_items_timestamp_idx on _hyper_5_2097_chunk  (cost=0.29..2944.74 rows=32369 width=196)
        Index Cond: ("timestamp" >= date_trunc('month'::text, now()))
        Filter: ((id)::text = 'xb1a'::text)

上面应该返回 51,386 (19017 + 32369)

我目前的功能如下

CREATE or replace FUNCTION count_estimate(query text) RETURNS integer AS $$
declare
  counter integer := 0;
  rec   record;
  rows  integer;
BEGIN
  FOR rec IN EXECUTE 'EXPLAIN ' || query loop
    counter := counter + 1;
    IF counter >= 1 THEN
        rows := substring(rec."QUERY PLAN" FROM ' rows=([[:digit:]]+)');
    end IF;
  END LOOP;
  RETURN rows;
END;
$$ LANGUAGE plpgsql VOLATILE STRICT;

【问题讨论】:

  • 您应该使用EXPLAIN (FORMAT JSON),它的机器可读性更强。
  • 我切换到了 json 格式,并在一条记录中得到了一个格式很好的解释版本,但我仍然不确定如何使用它来获取总行数。

标签: postgresql execute sql-execution-plan


【解决方案1】:

为此,使用EXPLAIN 的JSON 格式要容易得多。估计行数的函数可能如下所示:

CREATE FUNCTION estimate_rows(query text) RETURNS numeric
   LANGUAGE plpgsql STRICT AS
$$DECLARE
   j json;
BEGIN
   EXECUTE 'EXPLAIN (FORMAT JSON) ' || query
      INTO j;
   RETURN CAST(j -> 0 -> 'Plan' ->> 'Plan Rows' AS numeric);
END;$$;

【讨论】:

    猜你喜欢
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-08
    • 2016-01-18
    • 1970-01-01
    相关资源
    最近更新 更多