--------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("T3"."N"=1100)
4 - access("T3"."ID"="T4"."T3_ID")
SQL> select * from t3, t4 where t3.id = t4.t3_id and t3.n = 1100;
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------
SQL_ID c204pd6srpjfq, child number 0
-------------------------------------
select * from t3, t4 where t3.id = t4.t3_id and t3.n = 1100
Plan hash value: 2304842513
-------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
-------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 10 |00:00:00.01 | 17 | 1 |
| 1 | NESTED LOOPS | | 1 | | 10 |00:00:00.01 | 17 | 1 |
| 2 | NESTED LOOPS | | 1 | 10 | 10 |00:00:00.01 | 7 | 1 |
| 3 | TABLE ACCESS BY INDEX ROWID| T3 | 1 | 1 | 1 |00:00:00.01 | 4 | 1 |
|* 4 | INDEX RANGE SCAN | T3_N | 1 | 1 | 1 |00:00:00.01 | 3 | 1 |
|* 5 | INDEX RANGE SCAN | T4_T3_ID | 1 | 10 | 10 |00:00:00.01 | 3 | 0 |
| 6 | TABLE ACCESS BY INDEX ROWID | T4 | 10 | 10 | 10 |00:00:00.01 | 10 | 0 |
-------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("T3"."N"=1100)
5 - access("T3"."ID"="T4"."T3_ID")
从上面的执行计划中可以看出, 采用 nested loops 嵌套循环连接的 CPU 0.03 降为 0.01, buffers 从 108 降为 17, 因此,在等值连接条件且在连接列条件上有索引, 如果返回的数据量较少, 适合用嵌套循环连接; 如果返回的数据量比较大, 则适合用 hash 连接。
四. 小结
在大多数的情况下, 哈希连接的效率比嵌套循环连接和排序合并连接更高:
1. 哈希连接可能比嵌套循环连接快,因为处理内存中的哈希表比检索B树更加迅速。
2. 哈希连接可能比排序合并连接更快,因为这种情况下,只有一张源表需要排序,而且只是对 hash partition 排序。在排序合并连接中,两张表的数据都需要先做排序,然后做MERGE操作,因此效率相对最差。
?
hash 连接很适合一大一小的结果集连接返回大数据量的情形, 特别是 hash table 能够全部放在 hash area 的情况下, 这时候哈希连接的执行时间可以近似看做是全表扫描两个结果集的时间之和.
?
在 sql 调优时, 如果遇到表的连接方式是 hash 连接, 进行优化可以考虑以下几点:
1. 确认小结果集为驱动结果集
2. 如果有谓词条件, 考虑在谓词条件上增加索引
3. 确认涉及到的表和连接列被分析过, 如果连接列上的数据分布不均匀, 考虑在此列上收集直方图
4. 增加 hash_area_size 大小, 使哈希连接只在内存就能完成, 即保证 PGA hash area 能够容纳 hash 运算