更新时间:2026-02-06 GMT+08:00
分享

参数化路径的Hint

功能描述

指明参数化路径,条件谓词下推方式,包括predpush和use_remote_param。

语法格式

1
2
3
predpush( [@queryblock] src1 src2)
predpush( [@queryblock] src, dest)
use_remote_param

参数说明

  • @queryblock请参见指定Hint所处的查询块Queryblock章节,可省略,表示在当前查询块生效。
  • src,src1,src2表示predpush下推candidates一侧表集合。
  • dest表示predpush下推所指定的dest表也就是目标表。
  • predpush如果没有逗号表示所有表都是candidates表,如果有逗号就说明同时指定了candidates表和dest表。
  • 使用use_remote_param后会在当前queryblock启动下推语句的分布式计划的参数化路径功能。

使用predpush hint将过滤表达式尽可能移至靠近数据源的位置以达到查询优化的目的。

  • 使用predpush hint需要确保rewrite_rule GUC参数包含PREDPUSH|REDPUSHFORCE|PREDPUSHNORMAL选项。
  • subquery_block可以是视图/物化视图。

示例

灵活使用predpush hint、use_remote_param hint可以大幅提高语句的执行效率。示例如下:

CREATE TABLE pt2(a int, b int);
CREATE TABLE pt3(a int, b int);
CREATE TABLE pt4(a int, b int);
CREATE INDEX t4_a_idx on pt4(a);
CREATE INDEX t3_a_idx on pt3(a, b);
CREATE INDEX t2_a_idx on pt2(a);
SET rewrite_rule='predpushforce';
SET enable_fast_query_shipping = off;
SET explain_perf_mode=pretty;
gaussdb=# EXPLAIN (costs off) SELECT /*+PREDPUSH(pt2 st3) */ *
FROM pt2,
    (SELECT /*+ indexscan(pt3) indexscan(pt4)  */sum(pt3.b), pt3.a FROM pt3, pt4 where pt3.a = pt4.a GROUP BY pt3.a) st3
WHERE st3.a = pt2.a;
 id |                       operation
----+-------------------------------------------------------
  1 | ->  Streaming (type: GATHER)
  2 |    ->  Nested Loop (3,4)
  3 |       ->  Seq Scan on pt2
  4 |       ->  HashAggregate
  5 |          ->  Nested Loop (6,7)
  6 |             ->  Index Only Scan using t3_a_idx on pt3
  7 |             ->  Index Only Scan using t4_a_idx on pt4
(7 rows)
 Predicate Information (identified by plan id)
-----------------------------------------------
   6 --Index Only Scan using t3_a_idx on pt3
         Index Cond: (a = pt2.a)
   7 --Index Only Scan using t4_a_idx on pt4
         Index Cond: (a = pt2.a)
(4 rows)
SET enable_stream_operator=off;
SET enable_hashjoin=off;
SET enable_mergejoin=off;
CREATE INDEX ON pt3(b);
CREATE INDEX ON pt4(b);
gaussdb=# EXPLAIN (VERBOSE ON, COSTS OFF) SELECT /*+ USE_REMOTE_PARAM*/ 1 FROM PT2, PT3 WHERE PT2.A = 1 AND PT2.B = PT3.B AND EXISTS (SELECT /*+ NO_EXPAND*/ 1 FROM PT4 WHERE PT4.B = PT3.B);
                                       QUERY PLAN
-----------------------------------------------------------------------------------------
 Nested Loop
   Output: 1
   ->  Data Node Scan on pt2 "_REMOTE_TABLE_QUERY_"
         Output: pt2.b
         Node/s: datanode2
         Remote query: SELECT b FROM ONLY public.pt2 WHERE a = 1
   ->  Data Node Scan on pt3 "_REMOTE_TABLE_QUERY_"
         Output: pt3.b
         Node/s: All datanodes
         Remote query: SELECT/*+ No TableScan(pt3)*/ b FROM ONLY public.pt3 WHERE $1 = b
         Coordinator quals: (SubPlan 1)
         SubPlan 1
           ->  Data Node Scan on pt4 "_REMOTE_TABLE_QUERY_"
                 Node/s: All datanodes
                 Remote query: SELECT b FROM ONLY public.pt4 WHERE true
                 Coordinator quals: (pt4.b = pt3.b)
(16 rows)
  • 在未使用predpush hint的情况下,子查询中pt3、pt4在进行JOIN操作之前没有经过任何来自query block外的处理,所以返回的结果集较大,造成性能浪费。

    然而,如上所示的执行计划,在使用了predpush hint后,pt3、pt4在进行JOIN操作之前先基于pt2表进行了一次条件过滤,JOIN后返回的结果集较小,可以有效提升性能。

  • 在未使用use_remote_param的情况下,JOIN操作中pt3表需要进行全表扫描,然后与pt2进行JOIN,最后再通过JOIN条件过滤。整体处理的数据量较大,造成性能浪费。

    然而,如上所示的执行计划,在使用了use_remote_param的hint后,pt3在扫描时使用了pt2.b=pt3.b的条件进行过滤,再与pt2进行JOIN。整体处理的数据量较小,可以有效提升性能。

相关文档