云服务器内容精选

  • 注意事项 block_name hint仅在对应的子链接块提升时才会被上层查询使用。目前支持的子链接提升包括IN子链接提升、EXISTS子链接提升和包含Agg等值相关子链接提升。该hint通常会和前面章节提到的hint联合使用。 对于FROM关键字后的子查询,则需要使用子查询的别名进行hint,block_name hint不会被用到。 如果子链接中含有多个表,则提升后这些表可与外层表以任意优化顺序连接,hint也不会被用到。
  • 参数说明 block_name表示语句块的block_name,详细说明请参考block_name。 table表示为该子链接块hint的别名的名称。 表的语法格式如下: [schema.]table[@block_name] 表名可以带schema,也可以带所在子查询语句块提升前的block_name。子查询语句块在优化器进行优化重写时发生提升,则该block_name会与leading中block_name不同。 表如果存在别名,优先使用别名来表示该表。
  • 参数说明 join_table_list 为表示表join顺序的hint字符串,可以包含当前层的任意个表(别名),或对于子查询提升的场景,也可以包含子查询的hint别名,同时任意表可以使用括号指定优先级,表之间使用空格分隔。 join table list中指定的表需要满足以下要求,否则会报语义错误: list中的表必须在当前层或提升的子查询中存在。 list中的表在当前层或提升的子查询中必须是唯一的。如果不唯一,需要使用不同的别名进行区分。 同一个表只能在list里出现一次。 如果表存在别名,则list中的表需要使用别名。 表的语法格式如下: [schema.]table[@block_name] 表名可以带schema,也可以带所在子查询语句块提升前的block_name。子查询语句块在优化器进行优化重写时发生提升,则该block_name会与leading中block_name不同。 表如果存在别名,优先使用别名来表示该表。
  • 语法格式 单层圆括号(),仅指定join顺序,不指定内外表顺序。 1 2 leading(join_table_list) leading(@block_name join_table_list) 双层圆括号(()),同时指定join顺序和内外表顺序,内外表顺序仅在最外层生效。 1 2 leading((join_table_list)) leading(@block_name (join_table_list))
  • 参数说明 relname为查询中表table的名字,表有别名时,需要优先使用别名alias,此时relname=alias。当表名中有特殊符号,比如“@”、“.”时,relname需要用""括起来,以避免和查询块和schema名的声明重合。比如表名relnametest@1,需要写做"relnametest@1"。 schema为表所处的schema,可缺省,缺省时hint不区分schema对relname进行查找。 queryblock为表所处的queryblock,可缺省,缺省时hint不区分queryblock对relname进行查找。
  • 示例 gaussdb=# deallocate all; DEALLOCATE ALL gaussdb=# prepare p1 as insert /*+ no_gpc*/ into t1 select c1,c2 from t2 where c1=$1; PREPARE gaussdb=# execute p1(3); INSERT 0 1 gaussdb=# select * from dbe_perf.global_plancache_status where schema_name='public' order by 1,2; nodename | query | refcount | valid | databaseid | schema_name | params_num | func_id | pkg_id | stmt_id ----------+-------+----------+-------+------------+-------------+------------+---------+--------+--------- (0 rows) dbe_perf.global_plancache_status视图中无结果即没有计划被全局缓存。
  • Hint的错误、冲突及告警 Plan Hint的结果会体现在计划的变化上,可以通过explain来查看变化。 hint中的错误不会影响语句的执行,只是不能生效,该错误会根据语句类型以不同方式提示用户。对于explain语句,hint的错误会以warning形式显示在界面上,对于非explain语句,会以debug1级别日志显示在日志中,关键字为PLANHINT。 hint的错误分为以下类型: 语法错误 语法规则树归约失败,会报错,指出出错的位置。 例如:hint关键字错误,leading hint或join hint指定2个表以下,其它hint未指定表等。一旦发现语法错误,则立即终止hint的解析,所以此时只有错误前面解析完的hint有效。 例如: 1 leading((t1 t2)) nestloop(t1) rows(t1 t2 #10) nestloop(t1)存在语法错误,则终止解析,可用hint只有之前解析的leading((t1 t2))。 语义错误 表不存在、存在多个、或在leading或join中出现多次,均会报语义错误。 scanhint中的index不存在,会报语义错误。 如果子查询提升后,同一层出现多个名称相同的表,且其中某个表需要被hint,hint会存在歧义,无法使用,需要为相同表增加别名规避。 hint重复或冲突 如果存在hint重复或冲突,只有第一个hint生效,其它hint均会失效,会给出提示。 hint重复是指,hint的方法及表名均相同。例如:nestloop(t1 t2) nestloop(t1 t2)。 hint冲突是指,table list一样的hint,存在不一样的hint,hint的冲突仅对于每一类hint方法检测冲突。 例如:nestloop (t1 t2) hashjoin (t1 t2),则后面与前面冲突,此时hashjoin的hint失效。注意:nestloop(t1 t2)和no mergejoin(t1 t2)不冲突。 leading hint中的多个表会进行拆解。例如:leading ((t1 t2 t3))会拆解成:leading((t1 t2)) leading(((t1 t2) t3)),此时如果存在leading((t2 t1)),则两者冲突,后面的会被丢弃。(例外:指定内外表的hint若与不指定内外表的hint重复,则始终丢弃不指定内外表的hint。) 查询改写的hint允许重复,但对于重复的hint数据库只会使用第一个,对于其他未使用的hint则会报"unused hint" Warning提示。例如:/*+ expand_sublink expand_sublink */由于数据库只使用第一个expand_sublink Hint,所以仍然会报"unused hint" Warning提示。 子链接提升后hint失效 子链接提升后的hint失效,会给出提示。通常出现在子链接中存在多个表连接的场景。提升后,子链接中的多个表不再作为一个整体出现在join中。 hint未被使用 非等值join使用hashjoin hint或mergejoin hint。 不包含索引的表使用indexscan hint、index hint或indexonlyscan hint。 通常只有在索引列上使用过滤条件才会生成相应的索引路径,全表扫描将不会使用索引,因此使用indexscan hint、index hint或indexonlyscan hint将不会使用。 indexonlyscan只有输出和谓词条件列仅包含索引列才会使用,否则指定时hint不会被使用。 多个表存在等值连接时,仅尝试有等值连接条件的表连接,此时没有关联条件的表之间的路径将不会生成,所以指定相应的leading、join、rows hint将不使用,例如:t1 t2 t3表join,t1和t2,t2和t3有等值连接条件,则t1和t3不会优先连接,leading(t1 t3)不会被使用。 如果子链接未被提升,则blockname hint不会被使用。 父主题: 使用Plan Hint进行调优
  • 参数说明 no 不使用Partition-wise Scan查询改写。 @tablename 进行Partition-wise Scan的分区表,不可省略。 partitionwisescan 使用Partition-wise Scan对分区表进行并发扫描。 partitionwisescan只支持SMP场景下的分区表的扫描,支持SeqScan、IndexScan、IndexonlyScan、ImcvScan。
  • 语法格式 1 2 3 4 predpush_same_level(src, dest) predpush_same_level(src1 src2 ..., dest) [no] nestloop_index([@queryblock] dest[, index_list]) -- 索引方式 [no] nestloop_index([@queryblock] dest[,(src1 src2 ...)]) -- 表名方式 predpush_same_level参数仅在rewrite_rule中的predpushforce选项打开时生效。 nestloop_index对rewrite_rule不做要求。
  • 参数说明 @version_num:Outline的版本。不指定默认为1.0.0,当前仅支持1.0.0,为后续版本Outline行为控制做预留。 BEGIN_OUTLINE_DATA/END_OUTLINE_DATA:生成的Outline Hint,在使用时需要放在两者之间。 BEGIN_OUTLINE_DATA和END_OUTLINE_DATA必须成对使用。 当同时使用BEGIN_OUTLINE_DATA和END_OUTLINE_DATA时,只有两者之间的hint会生效。
  • 功能描述 Outline是描述执行计划的重要手段,也是计划固化的持久化表示。Outline存储在数据库中,需要在不同版本之间兼容,可以指导优化器生成指定计划。内核在生成执行计划的同时,可以生成Outline。同时优化器能够使用Outline对计划进行控制,Outline是计划管理的核心前提能力。 Outline Hint是优化器为了完全复现某一计划而生成的一组hint信息,以BEGIN_OUTLINE_DATA开始,并以END_OUTLINE_DATA结束。Outline Hint可以通过explain(outline on)获得。使用获得的Outline Hint能够对计划进行控制。
  • 特性约束 使用之前需要设置set explain_perf_mode = pretty选项。 Outline用于计划的复现还原,目前Outline可以控制同一条SQL的如下方面: 查询重写。 每层subquery的物理算子: a)扫描方式 b)连接方法 c)连接顺序 d)bitmap扫描的索引表 e)参数化路径 f)连接的内表物化 每层subquery的agg方法。 any子链接提升的额外处理:hashed或者material。 smp计划数据的传输方式。 目前内核的bitmapscan、indexscan、index Hint指定优化器在扫描相关表时,使用指定的索引产生索引扫描路径,具体的索引条件由优化器根据代价生成。 对于复杂多表连接的SQL,outline固定计划还原时,性能优于遗传算法。 当有Outline Hint时,对于在BEGIN OUTLINE和END OUTLINE包含以外的hint,若为控制计划生成的hint则全部失效处理(2,3,4点所提及的hint),若非控制计划生成的hint则保留,如wlmrule慢SQL管控规则的hint。
  • 参数说明 @queryblock请参见指定Hint所处于的查询块Queryblock,可省略,表示在当前查询块生效,该hint只在指定为最外层的queryblock时才会生效。 param表示参数名。 value表示参数的取值。 目前支持使用hint设置生效的参数有: 布尔类: enable_bitmapscan、enable_hashagg、enable_hashjoin、enable_indexscan、enable_indexonlyscan、enable_material、enable_mergejoin、enable_nestloop、enable_index_nestloop、enable_seqscan、enable_sort、enable_tidscan、partition_iterator_elimination、partition_page_estimation、enable_functional_dependency、var_eq_const_selectivity、enable_inner_unique_opt、enable_force_smp、enable_invisible_indexes 整型类: query_dop,multi_insert_min_rows, join_collapse_limit, from_collapse_limit 浮点类: cost_weight_index、default_limit_rows、seq_page_cost、random_page_cost、cpu_tuple_cost、cpu_index_tuple_cost、cpu_operator_cost、effective_cache_size 枚举类型: try_vector_engine_strategy 设置不在白名单中的参数,参数取值不合法,或hint语法错误时,不会影响查询执行的正确性。使用explain(verbose on)执行可以看到hint解析错误的报错提示。 GUC参数的hint只在最外层查询生效,子查询内的GUC参数hint不生效。 视图定义内的GUC参数hint不生效。 CREATE TABLE ... AS ...查询最外层的GUC参数hint可以生效。
  • Hint使用准备 为了方便了解hint的使用场景,手册提供了所有查询改写hint的应用示例(请参见Hint使用说明),相关建表语句和环境准备如下: 会话设置: SET client_encoding = 'UTF8'; CREATE SCHEMA rewrite_rule_test; SET current_schema = rewrite_rule_test; SET enable_codegen= off; 建表语句: CREATE TABLE rewrite_rule_hint_t1 (a INT, b INT, c INT, d INT); CREATE TABLE rewrite_rule_hint_t2 (a INT, b INT, c INT, d INT); CREATE TABLE rewrite_rule_hint_t3 (a INT, b INT, c INT, d INT); CREATE TABLE rewrite_rule_hint_t4 (a INT NOT NULL, b INT, c INT, d INT); CREATE TABLE rewrite_rule_hint_t5 (slot INTEGER NOT NULL,cid BIGINT NOT NULL,name CHARACTER VARYING NOT NULL) WITH (ORIENTATION = row); INSERT INTO rewrite_rule_hint_t5 (slot, cid, name) values(generate_series(1, 10),generate_series(1, 10),'records.storage.state'); ANALYZE rewrite_rule_hint_t5; CREATE TABLE rewrite_rule_hint_customer ( c_custkey INTEGER NOT NULL, c_name CHARACTER VARYING(25) NOT NULL, c_address CHARACTER VARYING(40) NOT NULL, c_nationkey INTEGER NOT NULL, c_phone CHARACTER(15) NOT NULL, c_acctbal NUMERIC(15, 2) NOT NULL, c_mktsegment CHARACTER(10) NOT NULL, c_comment CHARACTER VARYING(117) NOT NULL ); CREATE TABLE rewrite_rule_hint_orders ( o_orderkey INTEGER NOT NULL, o_custkey INTEGER NOT NULL, o_orderstatus CHARACTER(1) NOT NULL, o_totalprice NUMERIC(15, 2) NOT NULL, o_orderdate DATE NOT NULL, o_orderpriority CHARACTER(15) NOT NULL, o_clerk CHARACTER(15) NOT NULL, o_shippriority INTEGER NOT NULL, o_comment CHARACTER VARYING(79) NOT NULL );
  • 查询改写Hint列表 表1 查询改写支持的hint列表 序号 hint名称 描述 1 EXPAND_SUBLINK_HAVING 允许HAVING子句中的子链接提升。 2 NO_EXPAND_SUBLINK_HAVING 禁止HAVING子句中的子链接提升。 3 EXPAND_SUBLINK 允许对ANY/EXISTS类型子链接进行提升。 4 NO_EXPAND_SUBLINK 禁止对ANY/EXISTS类型子链接进行提升。 5 EXPAND_SUBLINK_TARGET 允许对TargetList中的子链接进行提升。 6 NO_EXPAND_SUBLINK_TARGET 禁止对TargetList中的子链接进行提升。 7 USE_MAGIC_SET 从主查询下推条件到子查询,先针对子查询的关联字段进行分组聚集,再和主查询进行关联,减少相关子链接的重复扫描,提升查询效率。 8 NO_USE_MAGIC_SET 禁止从主查询下推条件到子查询,将带有聚集算子的子查询提前和主查询进行关联。 9 EXPAND_SUBLINK_UNIQUE_CHECK 允许对无agg的子链接进行提升,子链接提升需要保证对于每个条件只有一行输出。 10 NO_EXPAND_SUBLINK_UNIQUE_CHECK 禁止对无agg的子链接进行提升。 11 NO_SUBLINK_DISABLE_REPLICATED 允许带有复制表的fast query shipping或者Stream场景的表达式子链接提升。 12 SUBLINK_DISABLE_REPLICATED 禁止带有复制表的fast query shipping或者Stream场景的表达式子链接提升。 13 NO_SUBLINK_DISABLE_EXPR 允许对表达式类型的子链接进行提升。 14 SUBLINK_DISABLE_EXPR 禁止对表达式类型的子链接进行提升。 15 ENABLE_SUBLINK_ENHANCED 允许子链接提升增强,支持对OR表达式等相关或非相关子链接提升。 16 NO_ENABLE_SUBLINK_ENHANCED 禁用子链接提升增强,禁止对OR表达式等相关或非相关子链接提升。 17 PARTIAL_PUSH Stream场景支持对listagg和arrayagg添加gather算子。 18 NO_PARTIAL_PUSH Stream场景禁止对listagg和arrayagg添加gather算子。 19 REDUCE_ORDER_BY 消减冗余的ORDER BY,外层查询对内层查询结果无排序要求时,可以减少不必要的ORDER BY提升查询效率。 20 NO_REDUCE_ORDER_BY 禁止消减不必要的ORDER BY。 21 REMOVE_NOT_NULL 消减不必要的NOT NULL条件,当列属性为NOT NULL时,可以消减查询条件中的IS NOT NULL判断。 22 NO_REMOVE_NOT_NULL 禁止消减IS NOT NULL条件判断。 23 LAZY_AGG 子查询与外层查询存在同样的GROUP BY条件,两层聚集运算可能导致查询效率低下,消除子查询中的聚集运算,以此提高查询效率。 24 NO_LAZY_AGG 禁用消除子查询中的聚集运算规则。 25 EXPAND_SUBQUERY 子查询提升,将子查询提升与上层做JOIN连接,优化查询效率。 26 NO_EXPAND_SUBQUERY 禁用子查询提升。 27 PUSHDOWN_HAVING 下推HAVING条件表达式。 28 NO_PUSHDOWN_HAVING 禁止下推HAVING表达式。 29 INLIST_TO_JOIN 控制使用inlist-to-join对SQL进行改写。 30 NO_INLIST_TO_JOIN 控制禁止使用inlist-to-join对SQL进行改写。 31 ROWNUM_PUSHDOWN 允许行号下推。 32 NO_ROWNUM_PUSHDOWN 禁止行号下推。 33 WINDOWAGG_PUSHDOWN 允许父查询中窗口函数的过滤条件下推到子查询。 34 NO_WINDOWAGG_PUSHDOWN 禁止父查询中窗口函数的过滤条件下推到子查询。 35 CS E_REWRITE_OPT 允许使用公共子表达式CSE查询重写将having公共子查询重写为窗口聚集函数。 36 NO_CSE_REWRITE_OPT 禁止使用公共子表达式CSE查询重写将having公共子查询重写为窗口聚集函数。 37 GROUPBY_PUSHDOWN_SUBQUERY 允许使用groupby-pushdown-subquery查询重写将groupby聚集函数下推到子查询。 38 NO_GROUPBY_PUSHDOWN_SUBQUERY 禁止使用groupby-pushdown-subquery查询重写将groupby聚集函数下推到子查询。