注册
达梦数据库:查询优化手段,思路及执行计划解读
培训园地/ 文章详情 /

达梦数据库:查询优化手段,思路及执行计划解读

南池 2023/08/25 2688 1 0

数据库执行一条语句有多种方式,为了选择最优的执行方式,产生了查询优化器。查询优化器分析语句运行时的所有因素,选择最优的方式去执行,提高了查询效率。因此,查询优化是数据库执行 SQL 语句的重要过程,决定了数据库的查询性能。

一、思路与目标
1.1 优化基本思路
遇到数据库性能问题,一般从操作系统、实例、SQL 三个方面进行分析。
操作系统:需要关注内存、CPU、I/O 信息。
实例层面:关注数据库架构、INI参数。
SQL层面:关注性能监控视图、SQL日志等。
1.2 查询优化步骤

1.3 查询优化目的
响应时间 越来越快 (响应耗时↓)
吞吐量 越来越多 (返回数据量↑)
达梦数据库查询优化器的优化目标为最快响应时间。

通过设置参数 FIRST_ROWS 来决定优先返回多少条记录给用户,而不需要等待全部结果确定后再输出,FIRST_ROWS 设置范围为 1~1000,单位为行。例如:FIRST_ROWS = 10,意思是查询出 10 条结果就立即返回给用户。可以根据实际情况,调整参数值。

二、查询优化器
查询优化器通过分析可用的执行方式和查询所涉及的对象统计信息来生成最优的执行计划。此外,如果存在 HINT 优化提示,优化器还需要考虑优化提示的因素。

查询优化器的处理过程包括:
(1)优化器生成所有可能的执行计划集合;
(2)优化器基于字典信息的数据分布统计值、执行语句涉及到的表、索引和分区的存储特点来估算每个执行计划的代价。代价是指 SQL 语句使用某种执行方式所消耗的系统资源的估算值。其中,系统资源消耗包括 I/O、CPU 使用情况、内存消耗等;
(3)优化器选择代价最小的执行方式作为该条语句的最终执行计划。

上述过程可简单概括成三个操作:查询转换、估算代价、生成计划。

2.1 查询转换
查询转换是指把经过语法、语义分析的查询块之间的连接类型、嵌套关系进行调整,生成一个更好的查询计划。常用的查询转换技术包括过滤条件的下放、相关子查询的去相关性。
过滤条件下放:在连接查询中,把部分表的过滤条件下移,在连接之前先过滤,可以减少连接操作的数据量,提升语句性能;
相关子查询的去相关性:把与子查询相关的外表与内表采用半连接的方式执行,放弃默认采取的嵌套连接方式,对性能有较大提升。
2.2 估算代价
估算代价是指对执行计划的成本进行估算。执行节点之间的代价值相关性较强,一个执行节点的代价包括该节点包含的子节点代价。

代价衡量指标包括选择率、基数、代价。

选择率是指满足条件的记录占总记录数的百分比。 记录集可以是基表、视图、连接或分组操作的结果集。选择率和查询谓词相关或者是谓词的连接相关。一个谓词可以看作是一个过滤器,过滤掉结果集中不满足条件的记录。选择率的范围从 0 到 1。其中,0 表示没有记录被选中,1 表示行集中所有记录都被选中。
如果没有统计信息,则优化器依据过滤条件的类型来设置对应的选择率。例如,等值条件的选择率低于范围条件选择率。这些假定是根据经验值,认为等值条件返回的结果集最少。
如果有统计信息,则可以使用统计信息来估算选择率。
基数是指整个行集的行数,该行集可以是基表、视图、连接或分组操作的结果集。

代价表示资源的使用情况。 查询优化器使用磁盘 I/O、CPU 占用和内存使用作为代价计算的依据,所以代价可以用 I/O 数、CPU 使用率和内存使用一组值来表示。所有操作都可以进行代价计算,例如扫描基表、索引扫描、连接操作或者对结果集排序等。

对单表过滤:定位查找、索引扫描。
对多表连接:连接顺序、连接方式。
影响代价的因素:

cardinality、byte、length(页大小、页数、聚簇因子)
操作符类型
参数配置
statistics
2.3 生成计划
生成计划指计划生成器对给定的查询按照连接方式、连接顺序、访问路径生成不同的执行计划,选择代价最小的一个作为最终的执行计划。

连接顺序:指不同连接项的处理顺序。连接项可以是基表、视图、或者是一个中间结果集。一个查询语句可能的计划数量是与 FROM 语句中连接项的数量成正比的,随着连接项的数量增加而增加。

访问路径:决定了从一个基表中获取数据所需要的代价。访问路径可以是基表扫描、索引扫描等。在进行基表扫描或索引扫描时,一次 I/O 读多个页,所以,基表扫描或索引全扫描的代价依赖于表的数据页数和多页读的参数值。二级索引扫描的代价依赖于 B 树的层次、需扫描的叶子块树以及根据 rowid 访问聚集索引的记录数。

连接代价:是指访问两个连接的结果集代价与连接操作的代价之和。

2.4 数据访问路径
访问路径指从数据库中检索数据的方法。一般情况下,索引访问用于检索表的小部分数据,全表扫描用于访问表的大部分数据。OLTP 应用中,一般使用索引访问路径,因为 OLTP中包含了许多高选择率的 SQL 语句。而决策支持系统则倾向于执行全表扫描来获取数据。

从数据库中定位和检索数据的方法有:全表扫描、聚集索引扫描、二级索引扫描等。

全表扫描:是指从基表中检索数据时,扫描该表中所有的数据。全表扫描方式适合检索表中大部分数据,这时比索引扫描更加有效率。

索引扫描:是指通过指定语句中的索引列进行遍历来检索表中的数据。索引扫描是从基于一列或多列的索引中检索数据。索引不仅包含索引值,还包含对应表中数据的 ROWID。如果需要访问的不是索引列,这时需要通过 ROWID 或聚集索引来找到表中的数据行。

索引扫描:包含聚集索引扫描和二级索引扫描。由于在聚集索引中,包含了表中所有的列值,所以检索数据时只需要扫描这一个索引就可以得到所有需要的数据。如果是二级索引,由于只包含索引列以及对应的 ROWID,如果查询列不在二级索引中则还需要扫描聚集索引来得到所需要的数据。

查询优化器选择访问路径基于以下几个因素:
(1)执行语句中可能的访问路径;
(2)估算每条执行路径的代价。 为了选择一个访问路径,优化器首先会通过检查语句中的 FROM 子句和 WHERE 子句中的条件表达式来决定哪一个访问路径可以使用。优化器会根据可用的访问路径生成可能的执行计划集合,然后使用索引、列和表的统计信息来估算每个计划的代价。最后,优化器选择最小代价的那个执行计划。

影响优化器选择访问路径的因素有语句中的提示(HINT)和统计信息。 用户可以在执行的语句中使用 HINT 来指定访问路径。而统计信息会根据表中数据的分布情况决定采用哪个访问路径会产生最小的代价。

2.5 连接
查询语句中 FROM 子句包含多个表时,我们称为连接查询。如 SELECT * FROM t1,t2 就是连接查询。

生成连接查询的执行计划,需要考虑访问路径、连接方式、连接顺序三方面因素。
(1)访问路径
对于每张表采用何种方式来获取数据。例如:全表扫描、索引扫描等。
查询优化器会估算每种扫描方式的代价,选择代价较小的访问路径。
(2)连接方式
确定两张表之间采用哪种连接方式。例如:哈希连接、嵌套连接、归并连接、外连接。

等值连接条件一般会选择哈希连接;非等值连接条件会采用嵌套连接;连接列均为索引列时,会采用归并连接。

嵌套连接:两张表进行非等值连接时会选择嵌套连接。相当于两张表进行笛卡尔集操作。此时,优化器会选择一张代价较小的表作为外表(驱动表),另一张表作为内表,外表的每条记录与内表进行一次连接操作。
哈希连接:两张表进行等值连接时会选择哈希连接。以一张表的连接列为哈希键,构造哈希表,另张表的连接列进行哈希探测,找到满足条件的记录。由于哈希命中率高,因此,在大数据量情况下,哈希连接的效率较高。哈希连接的代价是建立哈希表和哈希探测的代价。

归并连接:两张表的连接列均为索引列,则可以按照索引顺序进行归并,一趟归并就可以找出满足条件的记录。如果查询列也属于索引列的子集,则归并连接只需扫描索引,会有更好的性能表现。在两表连接条件不是等值(如<,<=,>,>=)情况下时,归并排序连接很有用。

外连接:外连接分为左外连接、右外连接、全外连接。作为外表的数据会全部返回,如果没有与外表匹配的记录,则填充 NULL 值。右外连接与左外连接的处理过程类似,只是外表不同,一个是左表,一个是右表。全外连接是进行左外连接和右外连接,返回两次外连接的 union 结果集。

子查询会转换成半连接。共有四种半连接方式:哈希半连接、索引半连接、嵌套半连接、归并半连接。等值连接条件会选择哈希/索引/归并半连接,非等值连接条件会选择嵌套半连接。

哈希半连接:以外表的连接列为 KEY 构造哈希表,内表的连接列进行探测来查找满足连接条件的记录;

索引半连接:如果子查询的连接列为索引前导列,可采用索引半连接。处理过程为外表的数据对子查询使用索引查找,返回满足条件的记录;

归并半连接:如果相关子查询的连接条件列均为索引列,可采用归并半连接。按照索引顺序,对外表、内表进行同步扫描,返回满足条件的记录;

嵌套半连接:如果连接条件为非等值,可转换为嵌套半连接。处理过程为外表的每条记录去遍历内表,返回满足条件的记录。

(3)连接顺序
当超过 2 张表进行连接时,就需要考虑表之间的连接顺序。不合适的连接顺序对执行效率有较大影响。一般原则是,经过连接可以产生较小结果集的表优先处理。
一个连接查询通常会对应多个执行计划,查询优化器会根据优化规则、代价估算挑选最优的执行计划。

三、统计信息
对象统计信息描述数据是如何在数据库中存储的。统计信息是优化器的代价计算的依据,可以帮助优化器较精确地估算成本,对执行计划的选择起着至关重要的作用。

达梦数据库的统计信息分三种类型:表统计信息、列统计信息、索引统计信息。
通过直方图来表示。

统计信息生成过程分以下三个步骤:

(1)确定采样的数据:根据数据对象,确定需要分析哪些数据。

表:计算表的行数、所占的页数目、平均记录长度
列:统计列数据的分布情况
索引:统计索引列的数据分布情况
(2)确定采样率:根据数据对象的大小,通过内部算法,确定数据的采样率。

采样率与数据量成反比。

(3)生成直方图:根据算法分析表的数据分布特征,确定直方图的类型。

有两种类型的直方图:频率直方图和等高直方图。

频率直方图的每个桶(保存统计信息的对象)的高度不同,等高直方图每个桶的高度相同。例如,对列生成统计信息,当列值分布比较均匀时,会采用等高直方图,否则,采用频率直方图。
在执行查询时,如果数据对象存在统计信息,代价算法可以根据统计信息中的数据,比较精确地计算出操作所需花费的成本,以此来确定连接方式、对象访问路径、连接顺序,选择最优的执行计划。

用户也可以通过修改 OPTIMIZER_DYNAMIC_SAMPLING 参数值在缺乏统计信息时进行动态统计信息收集。
DBMS_STATS.COLUMN_STATS_SHOW(USER, ‘TEST_TJ’,’AGE’);
—1.类型:频率直方图
—2.ENDPOINT_VALUE样本值: 1
—3.ENDPOINT_HEIGHT 样本值的个数:819
SELECT COUNT(*) FROM TEST_TJ WHERE AGE=1; —819
–查看统计信息:等高直方图
DBMS_STATS.COLUMN_STATS_SHOW(USER, ‘TEST_TJ’,‘ID’);
–解读统计信息
–1.类型:等高直方图
–2.ENDPOINT_VALUE样本值: 30
–3.ENDPOINT_HEIGHT小于样本值大于前一个样本值的个数:329
SELECT COUNT() FROM TEST_TJ WHERE ID<30; —329
–4.ENDPOINT_KEYGHT样本值的个数:11
SELECT COUNT() FROM TEST_TJ WHERE ID=30; —11
–5.ENDPOINT_DISTINCT小于样本值大于前一个样本值之间不同样本的个数: 30
SELECT COUNT(DISTINCT ID) FROM TEST_TJ WHERE ID<30; —30
四、执行计划
执行计划是 SQL 语句的执行方式,由查询优化器为语句设计的执行方式,交给执行器去执行。在 SQL 命令行使用 EXPLAIN 可以打印出语句的执行计划。
4.1 启动执行计划
建表和建索引语句:

CREATE TABLE T1(C1 INT,C2 CHAR);
CREATE TABLE T2(D1 INT,D2 CHAR);
CREATE INDEX IDX_T1_C1 ON T1(C1);
INSERT INTO T1 VALUES(1,’A’),(2,’B’),(3,’C’),(4,’D’);
INSERT INTO T2 VALUES(1,’A’),(2,’B’),(5,’C’),(6,’D’);
1
2
3
4
5
打印执行计划:

EXPLAIN SELECT A.C1+1,B.D2 FROM T1 A, T2 B WHERE A.C1 = B.D1;

执行计划如下:

该计划的大致执行流程如下:

CSCN2: 扫描 T2 表的聚集索引,数据传递给父节点索引连接;
NEST LOOP INDEX JOIN2: 当左孩子有数据返回时取右侧数据;
SSEK2: 利用 T2 表当前的 D1 值作为二级索引 IDX_T1_C1 定位查找的KEY,返回结果给父节点;
NEST LOOP INDEX JOIN2: 如果右孩子有数据则将结果传递给父节点 PRJT2否则继续取左孩子的下一条记录;
PRJT2: 进行表达式计算 C1+1, D2;
NSET2: 输出最后结果;
重复过程 1) ~ 4)直至左侧 CSCN2 数据全部取完。
执行过程为:控制流从上向下传递,数据流从下向上传递。
4.2 执行计划操作符

常用执行计划操作符包括以下几种:

NSET:收集结果集
用于结果集收集的操作符,一般是查询计划的顶层节点。

PRJT:投影
关系的“投影”(project)运算,用于选择表达式项的计算;广泛用于查询,排序,函数索引创建等。

SLCT:选择
关系的“选择” 运算,用于查询条件的过滤。

AAGR:简单聚集
用于没有group by的count sum age max min等聚集函数的计算。

FAGR:快速聚集
用于没有过滤条件时从表或索引快速获取MAX/MIN/COUNT值;DM数据库是世界上单表不带过滤条件下取COUNT值最快的数据库。

HAGR:HASH分组聚集
用于分组列没有索引只能走全表扫描的分组聚集,C2列没有创建索引。

SAGR:流分组聚集
用于分组列是有序的情况下,可以使用流分组聚集,C1上已经创建了索引,SAGR2性能优于HAGR2。

BLKUP:二次扫描
先使用2级别索引定位,再根据表的主键、聚集索引、rowid等信息定位数据行。

CSCN:全表扫描
CSCN2是CLUSTER INDEX SCAN的缩写即通过聚集索引扫描全表,全表扫描是最简单的查询,如果没有选择谓词,或者没有索引可以利用,则系统一般只能做全表扫描。在一个高并发的系统中应尽量避免全表扫描。

SSEK CSEK SSCN:索引扫描
SSEK2是二级索引扫描即先扫描索引,再通过主键、聚集索引、ROWID等信息去扫描表 CSEK2是聚集索引扫描只需要扫描索引,不需要扫描表 SSCN是索引全扫描,不需要扫描表。

五、其他
5.1 自适应计划
在 DM 优化器进行代价估算时,如果子节点是一个复杂查询,可能使得对于子节点的代价估算不准确,导致最终选择的计划在执行时并非最优计划。因此,DM 引入了自适应计划机制。

将 INI 参数 OPTIMIZER_MODE 和 ADAPTIVE_NPLN_FLAG 都置为 1,启用自适应计划机制。此时,优化器会自动判断在某些情况下,复杂查询的子节点可能导致代价估算不准确,则会为该节点生成一个备用计划节点。在实际执行到该节点时,根据准确的代价信息确定是否需要采用备用计划。

执行计划中有一个 ACTRL 操作符,说明优化器为这一条 SQL 语句生成了备用计划。ACTRL 是控制备用计划转换的操作符。 ACTRL 操作符计算下层孩子节点的代价,决定采用默认主计划还是备用计划。需要说明的是,MPP 和并行查询不支持自适应计划。

5.2 使用索引
为了提高查询效率,用户一般会在表中创建索引。查询中的条件列为索引列时,如果索引扫描代价最小,优化器就会采用索引扫描。

索引扫描有多种方式,例如,索引等值查询、索引范围查询。如果查询列属于索引列的子集,则通过索引扫描就可以获得数据,否则,还需要根据 ROWID 或者 PK 在聚集索引中定位记录。

常用的索引类型有唯一索引、组合索引、函数索引。 各自有不同的使用场景。
条件列具有 UNIQUE 约束,则可以创建唯一索引,减少索引扫描次数;
条件列是多个列,而且可以过滤掉大部分数据,可以在多个列上创建组合索引,把等值条件列作为组合索引的首列;
条件列使用确定性函数(同样环境下多次执行得到相同的结果),可以创建函数索引,会把函数值进行存储,使用方式与普通索引一样;
在空间数据应用中,可以创建空间索引提高空间查询的效率。
5.3 并行查询
并行查询(Parallel Query,PQ)是一种多个线程或进程间协作、共同完成 SQL 计 划的优化技术。

根据参与执行的 DM 服务器实例个数,并行查询可以划分为多机并行查询和单机并行查询。 单机并行查询仅利用了单机的 CPU、磁盘、内存等机器资源,因此又称为本地并行查询。

DM 支持本地并行和多机并行,并行查询具体实现上采用对称并行技术,即每一个执行者(进程或线程)都执行相同的计划。主要执行者负责向其他并行执行者分发计划、搜集数据并向客户返回最终结果。不管是主执行者,还是从执行者,它们执行的计划都是完全相同的。

5.4 查询计划重用
如果同一条语句执行频率较高,或者每次执行的语句仅仅是常量值不同,则可以考虑使用计划重用机制。避免每次执行都需要优化器进行分析处理,可以直接从计划缓存中获取已有的执行计划,减少了分析优化过程,提高执行率。

对于计划重用,达梦数据库提供了 INI 参数 USE_PLN_POOL 来控制,当置为非 0 时,会启用计划重用。

5.5 结果集重用
执行计划的生成与优化是一个非常依赖 CPU 的操作,而执行一个查询获得结果集也是一个非常消耗资源的操作。当系统连续执行两个完全相同的 SQL 语句,其执行计划和结果集很有可能是相同的,如果重新生成和执行计划,会大大浪费系统资源。这时如果使用计划重用和结果集重用,系统的响应速度可以大大提升。

结果集重用是基于计划重用的,如果查询的计划不能缓存,则其查询结果集必然不能缓存。 此外,当语句的游标属性为 FORWARD ONLY 时,默认查询不会生成结果集。而参数BUILD_FORWARD_RS 可以强制在此类查询中生成结果集,以便进行结果集重用。

可通过设置 INI 参数 RS_CAN_CACHE 来控制结果集重用。

当置为 0 时表示手动模式(MANUAL),在此模式下默认不缓存查询结果集,但是 DBA 可以通过语句提示等方法指示系统对必要的查询结果集进行缓存;

当置为 1 时表示强制模式(FORCE),在此模式下默认缓存所有可缓存结果集,但是 DBA 也可以通过新增的配置参数以及语句提示等方法取消某些不合适的结果集缓存。

当 RS_CAN_CACHE 为 1 时,还可以通过设置 INI 参数 RS_CACHE_TABLES 和RS_CACHE_MIN_TIME 对缓存的结果集进行限制和过滤。

DBA 可以通过在 SQL 语句中设置 “RESULT_CACHE”或“NO_RESULT_CACHE” HINT手动指示查询的结果集是否缓存。

select /+ RESULT_CACHE / id, name from sysobjects;
1
或者

select /+ NO_RESULT_CACHE / id, name from sysobjects;
1
在语句中使用 HINT 指定结果集缓存的优先级要高于 INI 中相关参数的设置。

还可以使用系统过程 SP_SET_PLN_RS_CACHE 来强制设置指定计划结果集缓存的生效及失效。 这个系统过程对结果集缓存的指定高于其它所有结果集缓存的设置。

在以下情况下,DM 不支持结果缓存:
(1)必须是单纯的查询语句计划,PL 脚本中包含查询语句也不能缓存结果集。
(2)查询语句的计划本身必须是缓存的。
(3)守护环境中的备库不支持结果集缓存。
(4)MPP 等集群环境下不支持结果集缓存(3、4 两点限制都是因为无法精确控制基表的数据更新时戳)。
(5)查询语句中包含以下任意一项,其结果集都不能缓存:

包含临时表;
包含序列的 CURVAL 或 NEXTVAL;
包含非确定的 SQL 函数或包方法(现有逻辑是不支持所有 SQL 函数或包方法);
包含 RAND、SYSDATE 等返回值实时变化的系统函数;
包含其它的一些实时要素。

关于达梦索引组织表和聚簇索引的一些总结
达梦数据库里,表(列存储表和堆表除外)都是使用 B+树索引结构管理的。每一个普通表都有一个聚集索引,数据通过聚集索引键排序,根据聚集索引键可以快速查询任何记录。

表和聚集索引是一体两面。整个表就是一个组合索引,这个组合索引包含表中所有字段。

当建表语句未指定时,DM 的默认聚集索引键是逻辑ROWID,即记录默认以 ROWID在页面中排序。ROWID 是逻辑递增序号,最新插入的记录 ROWID 最大。通常情况下,以 ROWID 建的默认聚集索引并没有什么实际意义。不能提高查询速度,因为实际情况下很少人根据逻辑ROWID来查找数据。

根据业务需要考虑是否创建表时指定索引键。(本文章为方便起见在建表后建的聚集索引,但实际情况几乎不会这么做。因为后续创建聚集索引相当于把整个表和上面的二级索引重建,非常耗时)

指定聚集索引键可以明显提高以它为条件的查询速度。但同时也会增加写入时间。这需要权衡。测试小结如下:

以条件字段为键值创建了聚集索引时查询效率最高(CSEK)。查询50%的数据用时与SSEK查询1%接近。因为不需要进行回表(BLKUP2)。显然聚集索引是有强大优势的。不过修改数据的代价则提高了不少。默认表加载测试数据用时52秒,其上建立了一个普通索引后加载同样数据用时4分32秒。不创建普通索引,代之为在该字段上创建聚集索引,加载同样数据则用时6分57秒。

当根据条件搜索的数据占比非常少时(比如千分之一)推荐建立普通B+树索引,虽然无论任何时候SSEK2都比不上CSEK2更快,但写入代价较低。当定位的数据较多时推荐建立聚集索引。只能有一个聚集索引,选择查询频率最高的字段作为索引键。

======================================

常用工具脚本:

2、查询阻塞
select trx_id,
thrd_id,
clnt_ip,
‘sp_close_session(‘ || sess_id || ‘);’,
state,
curr_sch,
sf_get_session_sql(sess_id),
datediff(ss, last_send_time, sysdate) ss,
sql_text
from v$sessions
where trx_id in
(select wait_trx_id
from v$dsc_trxwait a
where wait_trx_id not in (select trx_id from v$dsc_trxwait)); 两个节点都执行一下看看
3、查询锁
Select a.del_cnt,a.ins_cnt,a.upd_int,b,sql_text,b.clnt_ip from
v$trx a,v$sessions b where status=’ACTIVE’ and a.ID=b.trx_id

4、优化手册https://blog.csdn.net/liuyanwei1024/article/details/127490667?spm=1001.2101.3001.6650.7&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-127490667-blog-126450759.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-7-127490667-blog-126450759.pc_relevant_default&utm_relevant_index=12

5、常用参数:

5.1 问:我在一个达梦库上发现 select max(version) 返回的数字格式是 Decimal,而不是 number,请问这个是有什么配置影响吗
答:SP_SET_PARA_VALUE(2,’COMPATIBLE_MODE’,2) 这个是静态的得重启下。
COMPATIBLE_MODE:是否兼容其他数据库模式。0:不兼容,1:兼容SQL92标准,2:部分兼容ORACLE,3:部分兼容MS SQL SERVER,4:部分兼容MYSQL,5:兼容DM6,6:部分兼容TERADATA,7:部分兼容POSTGRES
5.2 SF_INJECT_HINT的用途:
一、SF_INJECT_HINT函数的作用
提供无需修改SQL语句但依然能按照指定的 HINT 运行语句的相关功能。
三、使用方法
SF_INJECT_HINT(‘需要加hint的sql(可以不需要具体的参数)’,‘NO_USE_CVT_VAR ENABLE_INDEX_JOIN(0)’, ‘INJECT1’, ‘to testfunction of injecting hint’, TRUE);
NO_USE_CVT_VAR ENABLE_INDEX_JOIN(0) —该项为所加的hint
SF_DEINJECT_HINT(‘INJECT1’); —使INJECT1所对应的sql所加的hint失效
INJECT1 —指定名称,可不指定,则系统自动创建
to testfunction of injecting hint —指定的hint描述,可为NULL
TRUE —规则是否生效,可为NULL,默认为TRUE
例:
SF_INJECT_HINT(
‘SELECT DISTINCT PART_A_STAMP_ID ID , PART_A_STAMP VALUE FROM SCP_SUP_CONTRACT_INFO
WHERE 1=1 and CONTRACT_TYPE = 0
and PART_A_STAMP_ID IS NOT NULL and PART_A_STAMP IS NOT NULL

ORDER BY PART_A_STAMP_ID',
‘SORT_FLAG(3)’,
‘HINT_SORT_0322_1’,
NULL,TRUE,TRUE
);

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服