暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL 15 preview - 递归查询work table记录数评估可自控, 新增GUC 参数 recursive_worktable_factor

原创 digoal 2022-01-20
1075

作者

digoal

日期

2022-03-25

标签

PostgreSQL , 递归 , work table 记录数评估


以前递归查询的work table记录数是代码写死的, work table平均记录数评估为非递归字句记录数的10倍:

rel->tuples = 10 * cte_rows;  

写死有个问题, 因为不同的递归场景, work_table的记录数实际上差异挺大.

  • 对于递归的图式全展开(每一层都不设置limit)查询, 每一个work table可能是上一级的N倍, 例如每个人关联10个人, 那么第一层10条, 第二层可能100条, 第三层可能1000条.
  • 对于最短路径查询每一层都limit 1条返回, 那么work table记录数就可以取初始记录的倍数为1.

PostgreSQL 15新增GUC recursive_worktable_factor (默认依旧是10), 倍数可以由用户自己控制.

https://www.postgresql.org/docs/devel/queries-with.html#QUERIES-WITH-RECURSIVE

https://www.postgresql.org/docs/devel/runtime-config-query.html#RUNTIME-CONFIG-QUERY-OTHER

recursive_worktable_factor (floating point)  
Sets the planner's estimate of the average size of the working table of a recursive query,   
as a multiple of the estimated size of the initial non-recursive term of the query.   
This helps the planner choose the most appropriate method for joining the working table to the query's other tables.   
The default value is 10.0.   
A smaller value such as 1.0 can be helpful when the recursion has low “fan-out” from one step to the next,   
as for example in shortest-path queries.   
Graph analytics queries may benefit from larger-than-default values.  

例子

WITH RECURSIVE t(n) AS (  
    VALUES (1)    -- non-recursive term  , 初始记录数  
  UNION ALL         
    SELECT n+1 FROM t WHERE n < 100  -- recursive query, 产出working table, 也就是要recursive_worktable_factor评估的平均每个working table的记录数.   
)  
SELECT sum(n) FROM t;  
/*  
 * set_cte_size_estimates  
 *      Set the size estimates for a base relation that is a CTE reference.  
 *  
 * The rel's targetlist and restrictinfo list must have been constructed  
 * already, and we need an estimate of the number of rows returned by the CTE  
 * (if a regular CTE) or the non-recursive term (if a self-reference).  
 *  
 * We set the same fields as set_baserel_size_estimates.  
 */  
void  
set_cte_size_estimates(PlannerInfo *root, RelOptInfo *rel, double cte_rows)  
{  
    RangeTblEntry *rte;  
    /* Should only be applied to base relations that are CTE references */  
    Assert(rel->relid > 0);  
    rte = planner_rt_fetch(rel->relid, root);  
    Assert(rte->rtekind == RTE_CTE);  
    if (rte->self_reference)  
    {  
        /*  
         * In a self-reference, we assume the average worktable size is a  
         * multiple of the nonrecursive term's size.  The best multiplier will  
         * vary depending on query "fan-out", so make its value adjustable.  
         */  
        rel->tuples = clamp_row_est(recursive_worktable_factor * cte_rows);  
    }  
    else  
    {  
        /* Otherwise just believe the CTE's rowcount estimate */  
        rel->tuples = cte_rows;  
    }  
    /* Now estimate number of output rows, etc */  
    set_baserel_size_estimates(root, rel);  
}  

递归用法参考:

《PostgreSQL 递归CTE 模拟一维空间的元胞自动机 - 复杂系统研究 自组织,涌现》
《PostgreSQL 递归查询 - 深度优先、广度优先 搜索举例 - BREADTH DEPTH》
《PostgreSQL 递归查询中不支持 order by, 聚合函数, 自包含子查询的》
《PostgreSQL 递归一例, 问题、回答、留言, 1对多对多的结构》
《森林状图式数据(树状) 的 高效生成方法》
《重新发现PostgreSQL之美 - 6 index链表跳跳糖 (CTE recursive 递归的详细用例)》
《PostgreSQL - 时序、IoT类场景 - first_value , last_value , agg , cte , window , recursive》
《PostgreSQL 14 preview - recovery 性能增强 - recovery_init_sync_method=syncfs - 解决表很多时, crash recovery 递归open所有file的性能问题 - 需Linux新内核支持》
《PostgreSQL 14 preview - SQL标准增强, 递归(CTE)图式搜索增加广度优先、深度优先语法, 循环语法 - breadth- or depth-first search orders and detect cycles》
《PostgreSQL 递归查询在分组合并中的用法》
《递归+排序字段加权 skip scan 解决 窗口查询多列分组去重的性能问题》
《PostgreSQL 排序去重limit查询优化 - 递归 vs group分组 (loop降到极限, block scan降到极限)》
《PostgreSQL 家族图谱、社交图谱、树状关系、藤状分佣、溯源、等场景实践 - 递归,with recursive query (有向无环 , 有向有环)》
《累加链条件过滤 - 递归、窗口、UDF、游标、模拟递归、scan 剪切》
《PostgreSQL 并行计算解说 之29 - parallel 递归查询, 树状查询, 异构查询, CTE, recursive CTE, connect by》
《PostgreSQL 递归应用实践 - 非“传销”的高并发实时藤、树状佣金分配体系》
《PostgreSQL 家谱、族谱类应用实践 - 图式关系存储与搜索》
《PostgreSQL 递归妙用案例 - 分组数据去重与打散》
《PostgreSQL Oracle 兼容性之 - INDEX SKIP SCAN (递归查询变态优化) 非驱动列索引扫描优化》
《PostgreSQL 图式搜索(graph search)实践 - 百亿级图谱,毫秒响应》
《PostgreSQL 实践 - 内容社区(如论坛)图式搜索应用》
《小微贷款、天使投资(风控助手)业务数据库设计(图式搜索\图谱分析) - 阿里云RDS PostgreSQL, HybridDB for PostgreSQL最佳实践》
《PostgrSQL 递归SQL的几个应用 - 极客与正常人的思维》
《PostgreSQL 递归查询CASE - 树型路径分组输出》
《用PostgreSQL找回618秒逝去的青春 - 递归收敛优化》
《distinct xx和count(distinct xx)的变态递归优化方法 - 索引收敛(skip scan)扫描》
《时序数据合并场景加速分析和实现 - 复合索引,窗口分组查询加速,变态递归加速》
《PostgreSQL雕虫小技cte 递归查询,分组TOP性能提升44倍》
《PostgreSQL 使用递归SQL 找出数据库对象之间的依赖关系 - 例如视图依赖》
《PostgreSQL 递归死循环案例及解法》
《PostgreSQL 递归查询一例 - 资金累加链》
《PostgreSQL Oracle 兼容性之 - WITH 递归 ( connect by )》
《递归优化CASE - group by & distinct tuning case : use WITH RECURSIVE and min() function》
《递归优化CASE - performance tuning case :use cursor\trigger\recursive replace (group by and order by) REDUCE needed blockes scan》
《PostgreSQL 树状数据存储与查询(非递归) - Use ltree extension deal tree-like data type》

期望 PostgreSQL 增加什么功能?

PolarDB for PostgreSQL云原生分布式开源数据库

PostgreSQL 解决方案集合

德哥 / digoal's github - 公益是一辈子的事.

digoal's wechat

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论