1 JOIN顺序控制类Hint
| Hint类型 | 作用描述 | 使用示例 | 与LEADING协同要点 |
|---|---|---|---|
LEADING |
精确控制JOIN顺序和内外表关系(最灵活) | /*+ LEADING((A B) C) */ |
基础框架,定义整体执行路径 |
ORDERED |
强制按FROM子句顺序JOIN(不控制内外表) | /*+ ORDERED */ |
LEADING的简化版,不指定内外表关系时替代 |
SWAP_JOIN_INPUTS |
交换指定表的JOIN方向(内外表转换) | /*+ SWAP_JOIN_INPUTS(B) */ |
微调LEADING定义的特定JOIN方向 |
顺序要求:
LEADING中表必须存在且唯一(用别名)括号层次决定内外表关系:
(外表 内表)无依赖冲突(如外键约束)
2 JOIN算法选择类Hint
| Hint类型 | 适用场景 | 使用示例 | 与LEADING协同要点 |
|---|---|---|---|
USE_NL |
小表驱动大表,高选择性索引 | /*+ USE_NL(A B) */ |
在LEADING定义顺序后指定特定JOIN的算法 |
USE_HASH |
大数据量等值JOIN,无高效索引 | /*+ USE_HASH(B C) */ |
常与LEADING联用处理事实表JOIN |
USE_MERGE |
大数据量非等值JOIN(>,<,BETWEEN) | /*+ USE_MERGE(C D) */ |
需LEADING确保输入集已排序 |
NO_USE_NL |
强制排除嵌套循环 | /*+ NO_USE_NL(A B) */ |
防止优化器覆盖LEADING的计划 |
组合示例:
/*+ LEADING(A (B C))
USE_NL(A B) -- A驱动B用嵌套循环
USE_HASH(B C) */ -- B和C用哈希JOIN
SELECT *
FROM A, B, C
WHERE A.id=B.id AND B.key=C.key;
3 索引优化类Hint
| Hint类型 | 作用描述 | 使用示例 | 与LEADING协同要点 |
|---|---|---|---|
INDEX |
强制使用特定索引 | /*+ INDEX(A idx_name) */ |
优先为LEADING的驱动表指定索引 |
INDEX_JOIN |
通过索引直接JOIN避免表扫描 | /*+ INDEX_JOIN(A B) */ |
减少LEADING中间结果集大小 |
NO_INDEX |
禁止使用特定索引 | /*+ NO_INDEX(A idx_bad) */ |
避免低效索引干扰LEADING顺序 |
驱动表索引优先原则:
/*+ LEADING(orders customers)
INDEX(orders idx_order_date) */ -- 为驱动表orders指定索引
SELECT *
FROM orders, customers
WHERE orders.cust_id = customers.id
AND orders.order_date > SYSDATE-30;
4 并行执行类Hint
| Hint类型 | 作用描述 | 使用示例 | 与LEADING协同要点 |
|---|---|---|---|
PARALLEL |
设置表/查询的并行度 | /*+ PARALLEL(8) */ |
全局生效,支持LEADING定义的结构 |
PQ_DISTRIBUTE |
控制并行数据分发方式 | /*+ PQ_DISTRIBUTE(B HASH HASH) */ |
优化LEADING中特定JOIN的并行效率 |
5 多表JOIN Hint综合应用框架
5.1 最佳实践工作流
-
定义JOIN骨架 → 用
LEADING确定顺序和内外表关系/*+ LEADING((A B) C) */ -
指定关键算法 → 为高成本JOIN添加算法Hint
/*+ USE_HASH(B C) */ -
优化驱动表访问 → 为LEADING中的第一个表添加索引Hint
/*+ INDEX(A pk_index) */ -
设置并行策略 → 根据数据量添加并行控制
/*+ PARALLEL(4) */ -
排除干扰因素 → 禁用低效索引或算法
/*+ NO_INDEX(A deprecated_idx) */
5.2 典型场景Hint配置模板
场景1:星型模型(事实表+多维度)
/*+ LEADING(sales dim1 dim2 dim3)
USE_HASH(sales dim1) -- 事实表与核心维度哈希JOIN
USE_NL(dim1 dim2) -- 维度间嵌套循环
INDEX(sales idx_sales_date) -- 为驱动表索引
PARALLEL(8) */
SELECT ...
FROM sales, dim1, dim2, dim3
WHERE ...
场景2:链式JOIN(A→B→C)
/*+ LEADING(A (B C)) -- A驱动B,结果再驱动C
USE_NL(A B) -- A→B用嵌套循环
USE_MERGE(B C) -- B→C用排序合并
INDEX(A idx_a_key)
NO_INDEX(B idx_b_slow) */ -- 禁用低效索引
SELECT ...
FROM A, B, C
WHERE A.id=B.id AND B.key=C.key;
场景3:子查询提升优化
/*+ LEADING(@subq main) -- 子查询结果作为驱动表
USE_HASH(main detail) */
SELECT /*+ QB_NAME(main) */ *
FROM (SELECT /*+ QB_NAME(subq) */ ...) subq,
detail_table detail
WHERE subq.id = detail.id;
5.3 关键注意事项
-
作用域冲突:
-
LEADING定义的顺序优先级 > 优化器自主选择 -
算法Hint仅影响指定表对(如
USE_NL(A B)不影响B-C的JOIN)
-
-
验证工具:
EXPLAIN PLAN FOR /*+ YOUR_HINTS */ SELECT ...; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); -
调试顺序:
当Hint不生效时:-
检查别名一致性
-
确认无语法错误(如缺失括号)
-
验证表/索引是否存在
-
使用
OPT_PARAM('_optimizer_ignore_hints' 'false')强制启用
-
通过将
LEADING作为JOIN优化的骨架,结合算法选择、索引优化和并行控制三类Hint,可实现对复杂多表JOIN的精确性能调控。
posted on
浙公网安备 33010602011771号