首页 时政热点 科技头条 智能AI 安全攻防 数码硬件 开发者生态 汽车 游戏 社会热点 开源推荐 医疗健康 归档 标签 关于

pg_clickhouse v0.10:子查询下推和 1000 倍更快的 TPC-H 查询

摘要

Continuing our investment in pg_clickhouse, improving pushdown coverage for analytic workloads has remained our top focus, with full pushdown across the TPC-H benchmark suite as our immediate metric. ...

the our pg_clickhouse down and TPC that query queries pushed
2026-08-12 1 阅读 约8分钟阅读 saisrirampur
分享:
字号:
继续我们对 pg_clickhouse 的投资,提高分析工作负载的下推覆盖率仍然是我们的首要关注点,并将 TPC-H 基准套件的全面下推作为我们的直接指标。自 6 月份的上次更新以来,我们已经取得了很多进展,包括 TPC-H 记分牌,自从 12 月份的介绍性帖子以来我们还没有真正讨论过这一点,所以这就是我们开始的地方。随着 v0.10.0 的发布,我们的记分板已从 22 个 TPC-H 查询中的 12 个完全减少到 16 个,只剩下 6 个可以完成该组查询。在此过程中,我们还在新的纯 C 客户端库上重建了二进制驱动程序,将下推的函数和聚合的表面积增加了一倍以上,并针对一些并发错误强化了二进制驱动程序,详情如下。现在,另外三个 TPC-H 查询已完全下推。这三个方法之前效率都非常低,因为由于查询的形状,pg_clickhouse 必须单独从 ClickHouse 获取每一行,然后在本地评估子查询(完整图表): Query PostgreSQL pg_clickhouse 0.3 pg_clickhouse 0.10 Pushdown Q2 588 ms 3,446 ms 24 ms ✔ Q17 2107 ms 32,709 ms 37 ms ✔ Q22 270 ms 1,415 ms 45 ms ✼(✔ = 整个查询是单个外部扫描)(✼ = 下推,但作为多个远程查询;通常是外部扫描加上一个 InitPlan 扫描。)Q17 是奖杯:一个相关子查询,每个部分平均 l_quantity,当它以比例因子 1 对 6M 行项目每个外部行评估一次时,花费了 32.7 秒。完全按下去,是 37 毫秒。这是三个数量级的差异,并且清楚地表明 pg_clickhouse 优于本机 PostgreSQL 自己的相同查询计划(2.1 秒)。六个查询仍未推送:Q13、Q15、Q16、Q18、Q20、Q21。 Q16和Q18为我们指明了前进的方向; pg_clickhouse 已经下推了他们需要的 SQL 形状( IN 和 NOT IN 被解析为反/半连接,如 Q2 和 Q17 中所示);阻碍它们的是 PostgreSQL 将它们的子查询扁平化为反/半连接,其输入本身就是 join ,并且解析器尚未在连接两侧遍历连接树。 Q15 和 Q20 遇到了同一问题的变体。这是子查询下推的下一个有凝聚力的部分。 12 月的头条新闻是教规划器将整个相关的 EXISTS 子查询向下推为单个 LEFT SEMI JOIN,而不是每个外行一次 ClickHouse 往返的嵌套循环。这将 22 个 TPC-H 查询中的 3 个一直增加到 12 个。剩下的 10 个查询有一个共同的问题:规划器根本无法将子查询折叠到连接中,因此它留下了一个子计划。这是查询计划的一部分,描述了作为执行完整查询的一部分运行的单独查询的完整计划,通常每行一次。推动这一点是我们路线图上的第五项,我们在最新版本 (0.10.0) 中将其淘汰 (#289)。现在,Postgres 中的子查询成为 ClickHouse 中的子查询: 1 EXPLAIN (VERBOSE, COSTS OFF) 2 SELECT s.sale_id, s.amount FROM sales s 3 WHERE s.amount > ( SELECT 1.5 * avg (s2.amount) FROM sales s2 4 WHERE s2.item_id = s.item_id) 5 ORDER BY s.sale_id;复制命令 1 对 subplan_test.sales s 进行外部扫描 2 输出:s.sale_id, s.amount 3 远程 SQL: SELECT sale_id, amount FROM subplan_test.sales r1 WHERE ((r1.amount > ( SELECT ( 1.5 * avg(q1_1.amount)) FROM subplan_test.sales q1_1 WHERE ((q1_1.item_id = (r1.item_id)))))) ORDER BY r1.sale_id ASC NULLS LAST 4 SubPlan expr_1 5 -> 外部扫描 6 输出:(( 1.5 * avg(s2.amount))) 7 关系:聚合 (sales s2) 8 远程 SQL:SELECT ( 1.5 * avg(amount)) FROM subplan_test.sales WHERE ((item_id = {p1:Int32})) 9 ( 8 rows) Copy 命令 EXPLAIN 仍然显示 SubPlan 节点(这只是 PostgreSQL 的相关性簿记),但您可以看到顶部的 Remote SQL 在我们发送到 ClickHouse 的一条语句中包含整个比较,包括子查询。同样的机制使得 pg_clickhouse 能够下推整个 TPC-H Q2:一次外部扫描和一次远程查询。只要规划器可以证明转换安全,NOT IN 就会通过 LEFT ANTI JOIN(v0.1.0 半连接的否定表亲)获得相同的处理。请注意,这些在 ClickHouse 25.8 以下都不起作用,因为它不支持相关子查询 SQL 形状; pg_clickhouse 在计划时检查服务器版本,并回退到旧服务器上的本地评估,就像它对不受支持的形状所做的那样。下推 SQL 是最简单的部分。更困难的部分是确保它计算出与 PostgreSQL 相同的答案(#315、#317),而这就是它自己的兔子洞。 ClickHouse 的 IN 运行在二值逻辑上,PostgreSQL 运行在三值逻辑上。这意味着 PostgreSQL 中的 x NOT IN (1, NULL) 可以为 FALSE ( x=1 ) 或 NULL,但绝不能为 TRUE 。天真地推下去,这些表达式可以在比较中涉及 NULL 的地方默默地反转结果,WHERE NOT IN 返回行 PostgreSQL 会过滤掉,GROUP BY 合并 NULL 组 i
这篇文章对您有帮助吗?

订阅66必读

每日精选科技资讯,直达你的邮箱