流程:
1. 生成 Row Source 1,按连接键 (A.COL3) 排序
2. 生成 Row Source 2,按连接键 (B.COL4) 排序
3. 双指针合并:同步游标扫描两有序流,匹配行输出
流程:
FOR each row in Outer (驱动表) LOOP
在 Inner (被驱动表) 查找匹配行 (索引/全扫)
输出匹配行
END LOOP
FIRST_ROWS 场景。流程:
1. 用较小行源构建 Hash Table + Bitmap (内存中)
2. 扫描较大行源,计算连接键 Hash,探测 Hash Table
3. Bitmap 快速过滤无匹配行,减少 Hash 桶探测
4. 匹配行输出
HASH_JOIN_ENABLED=TRUE (默认开)。HASH_AREA_SIZE (或 PGA_AGGREGATE_TARGET 自动管理),内存不足时分区溢写 TEMP,性能断崖下跌。SELECT A.DNAME, B.SQL FROM DEPT A, EMP B WHERE A.DEPTNO = B.DEPTNO;
-- NESTED LOOPS
-- TABLE ACCESS FULL DEPT
-- TABLE ACCESS FULL EMP
SELECT /*+ USE_HASH(EMP) */ EMPNO FROM EMP, DEPT WHERE EMP.DEPTNO = DEPT.DEPTNO;
-- HASH JOIN
-- TABLE ACCESS FULL DEPT
-- TABLE ACCESS FULL EMP
| 场景 | 首选 | 备选 |
|---|---|---|
| 小表驱动大表 + 索引 | NL | HJ |
| 大表连接大表 + 等值 + 内存充足 | HJ | SMJ |
| 非等值连接 | SMJ | NL (过滤后小) |
| 需首行快速返回 | NL | - |
| 并行查询 | HJ (并行 Hash) | SMJ (并行排序) |
核心提示:统计信息准确性是优化器选对算法的前提,定期 DBMS_STATS.GATHER_TABLE_STATS 并设置 METHOD_OPT=>'FOR ALL COLUMNS SIZE AUTO' 收集直方图。