在DM数据库中,对进行人工干预,指示优化器按照指定方法去选择 SQL 的执行计划的这种方式称为HINT。HINT用于使用优化器提示,hint的设置方式有9种(这里只介绍常用的五种)。
1.INI参数提示
2.索引提示
3.连接方法提示
4.连接顺序提示
5.统计信息提示
6.MPP本地对象提示
7.忽略重复键值提示
8.禁用计划缓存提示
9.DMDPC数据分发方式提示
注意:
如果 HINT 的语法没有写对或指定的值不正确,DM 并不会报错,而是直接忽略 HINT 继续执行
支持使用 HINT 的 INI 参数可通过 V$HINT_INI_INFO 动态视图查询。
上面视图的 PARA_NAME 列展示参数名,HINT_TYPE 列展示支持的 HINT 类型;
支持 HINT 的 INI 参数分为两类:
一是 HINT_TYPE 为"EXEC",表示运行阶段使用的参数,需要放在最外层的 SELECT 语句中,置于 SELECT 子句中不生效;
二是 HINT_TYPE 为"OPT",表示分析阶段使用的参数,不要求放在最外层的 SELECT 语句中,但其中部分参数需要保持全局一致,即需要和上层的参数值保持一致。需要保持全局一致的参数,例如:并行度"PARALLEL"。
DBA 可以通过 HINT 方式对 INI 参数的值进行语句级的指定。语句中的 HINT 对 INI参数值的设置优先级高于 INI 文件中参数值的设置。通过 HINT 方式只会修改 INI 参数的在本会话中的值,不会改变它在 INI 文件中的值。
具体参数名的含义说明,可以参考文档《DM8系统管理员手册》第二章2.1小节的配置文件。
查看ini参数信息。
例如:上图中第一个参数PL_SQL_STRIP的说明
/*+ INI参数名(参数值) */
通过调整ini参数来进行性能优化。如设置内存总和百分比、共享内存缓冲区大小等,可以提升数据库的查询速度和响应时间。
SELECT /*+ ENABLE_HASH_JOIN(1) */ * FROM T1,T2 WHERE C1=D1;
上面的语句中使用了 HINT,指明在执行此 SQL 时参数 ENABLE_HASH_JOIN 被置为 1。
hint索引提示,是一种用于数据库查询优化的技术。它允许用户显式地告诉数据库查询优化器,在执行特定查询时应使用哪个索引。
通过它,用户可以强制或建议数据库查询优化器为某个查询语句使用特定的索引。这有助于在特定情况下优化查询性能,尤其是当优化器自动选择的索引不是最优时。
表名 + INDEX + 索引名
/*+ INDEX (表名[,] 索引名) {INDEX (表名[,] 索引名)} /
一个语句中最多指定 8 个索引。在后一种语法格式中,如果查询中给出了表的别名那么必须使用别名。
与索引提示正好相反
语法:
/*+ NO_INDEX (表名[,] 索引名) { NO_INDEX (表名[,] 索引名)} */
可以指定多个索引,则这些索引都不能被使用。一个语句中最多指定 8 个索引。
通过指定两个表间的连接方法来检测不同连接方式的查询效率,指定的连接可能由于无法实现或代价过高而被忽略。如果连接方法提示中的表名(别名)或索引名无效也会被自动忽略。
1,USE_HASH
强制两个表间使用指定顺序的哈希连接,例如:
EXPLAIN SELECT /*+ USE_HASH(T1, T2) / * FROM T1, T2 WHERE T1.ID = T2.ID;
2,NO_USE_HASH
强制两个表间不能使用指定顺序的哈希连接,例如:
EXPLAIN SELECT /+ NO_USE_HASH(T1, T2) / * FROM T1, T2 WHERE T1.ID = T2.ID;
NO_USE_HASH(T1, T2)表示不允许 T1 作为左表, T2 作为右表的哈希连接,但 T1 作
为右表的哈希连接还是允许的。
3,USE_NL
强制两个表间使用嵌套循环连接,例如:
EXPLAIN SELECT /+ USE_NL(A, B) / * FROM T1 A, T2 B WHERE A.ID = B.ID;
4,NO_USE_NL
强制两个表间不能使用嵌套循环连接,例如:
EXPLAIN SELECT /+ NO_USE_NL(A, B) / * FROM T1 A, T2 B WHERE A.ID = B.ID;
5,USE_NL_WITH_INDEX
当连接情况为左表+右表索引时,强制两个表间使用索引连接,例如:
EXPLAIN SELECT /+ USE_NL_WITH_INDEX(T1, IDX_T2_ID) / * FROM T1, T2 WHERE
T1.ID = T2.ID;
6,NO_USE_NL_WITH_INDEX
当连接情况为左表+右表索引时,强制两个表间不能使用索引连接,例如:
EXPLAIN SELECT /+ NO_USE_NL_WITH_INDEX(T1, IDX_T2_ID) / * FROM T1, T2 WHERE T1.ID
= T2.ID;
7,USE_MERGE
强制两个表间使用归并连接。归并连接所用的两个列都必须是索引列。例如:
EXPLAIN SELECT /+ USE_MERGE(T1,T2) */ * FROM T1, T2 WHERE T1.ID = T2.ID AND
T1.ID < 1 AND T2.ID < 1;
当连接类型为外连接时,无法使用归并连接,此时即使指定 USE_MERGE,也不起作用。
8,NO_USE_MERGE
强制两个表间不能使用归并连接,例如:
EXPLAIN SELECT /+ NO_USE_MERGE(T1,T2) / * FROM T1, T2 WHERE T1.ID = T2.ID AND
T1.ID > 1 AND T2.ID > 1;
多表连接时优化器会考虑各种可能的排列组合顺序。使用 ORDER HINT 指定连接顺序提示可以缩小优化器试探的排列空间,进而得到接近 DBA 所期望的查询计划。如果连接顺序和连接方法提示同时指定且二者间存在自相矛盾,优化器会以连接顺序提示为准。
/*+ ORDER (T1, T2 , T3, … tn ) */
驱动表与被驱动表:
驱动表是表连接中的基础表,也就是通过驱动表的数据结果集作为循环基础数据,然后一条一条的通过这个结果集的数据作为过滤条件到被驱动表中查询数据,然后合并。
左连接中 左表是驱动表,右表是被驱动表
右连接中 右表是驱动表,左表是被驱动表
join查询的优化思路:用小表驱动大表,同时考虑在大表(被驱动表)上建立索引,索引被驱动表命中,从而避免大表(被驱动表)的全表遍历。
SELECT /+ ORDER(T1, T2, T3 )/* FROM T1, T2 , T3, T4 WHERE …
在指定上述连接顺序后,T4,T1,T2,T3 或 T1,T2,T4,T3 会被考虑;T3,T1,T2 或T1,T3,T2 不被考虑。
可以手动设置表的行数等统计信息,以影响优化器的查询计划选择。统计信息提示只能针对基表设置,视图和派生表等对象设置无效。如果表对象存在别名则必须使用别名。
行数只能使用整数,或者整数 +K(千),整数 +M(百万),整数 +G(十亿)。
行数提示设置后,统计信息的其它内容也会做相应的调整。
/*+ STAT (表名, 行数) */
优化器在计划优化阶段会自动获取基表的行数。但是一些特殊类型的表行数估算并不准确,或者 DBA 希望了解表大小对计划影响的时候,需要手动设置表的行数。
CREATE TABLE T_S(C1 INT);
INSERT INTO T_S SELECT LEVEL FROM DUAL CONNECT BY LEVEL<= 100;
COMMIT;
STAT 100 ON T_S(C1);
EXPLAIN SELECT /*+ STAT(T_S,1M) */ * FROM T_S WHERE C1 <= 10;
计划如下:
1 #NSET2: [117, 100000, 16]
2 #PRJT2: [117, 100000, 16]; exp_num(2), is_atom(FALSE)
3 #SLCT2: [117, 100000, 16]; T_S.C1 <= 10
4 #CSCN2: [117, 1000000, 16]; INDEX33555897(T_S)
不使用 HINT 时计划:
1 #NSET2: [0, 10, 16]
2 #PRJT2: [0, 10, 16]; exp_num(2), is_atom(FALSE)
3 #SLCT2: [0, 10, 16]; T_S.C1 <= 10
4 #CSCN2: [0, 100, 16]; INDEX33555897(T_S)
参考资料:
1,《DM8系统管理员手册》
2,https://eco.dameng.com/document/dm/zh-cn/pm/sql-tuning#23.6.5%20%E7%BB%9F%E8%AE%A1%E4%BF%A1%E6%81%AF%E6%8F%90%E7%A4%BA
文章
阅读量
获赞