To make up for the limitations of nested loop connections, that is, when the data volume is large, to reduce the number of random reads in nested loop connections, and when the connection column does not have an index, nested loop connections can be replaced.
However, to achieve table join, it must first sort the rows in the two tables that will be connected. Although this method improves the connection efficiency, the cost of connection is increased due to the existence of sorting. If you can quickly complete the sorting operation (sort_area_size) in parallel, it is a good choice to sort and merge connections when processing large amounts of data.
If an index exists in the connected column and the index is used to read data, the sorting operation of external row sources can be eliminated because the index is ordered.
The sort and merge joins do not have the concept of driving tables in nested loop joins.
- SQL> createtable t1 asselect * from dba_objects;
- The table has been created.
- SQL> createtable t2 asselect * from dba_objects;
- The table has been created.
- SQL> set autot traceonly
- SQL> set linesize 120
- SQL> select/* + use_merge (t1, t2) + */t1.object _ id, t1.object _ name, t2.object _ name
- 2 from t1, t2
- 3 where t1.object _ id = t2.object _ id;
- Row 50425 has been selected.
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 412793182
- Bytes ------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | TempSpc | Cost (% CPU) | Time |
- Bytes ------------------------------------------------------------------------------------
- | 0 | select statement | 53430 | 8244K 4k | 2379 (2) | 00:00:29 |
- | 1 | merge join | 53430 | 8244K 4k | 2379 (2) | 00:00:29 |
- | 2 | sort join | 53430 | 4122K | 9304K | 1152 (2) | 00:00:14 |
- | 3 | table access full | T1 | 53430 | 161 | (2) | 00:00:02 |
- | * 4 | sort join | 57436 | 4431K | 9M | 1227 (2) | 00:00:15 |
- | 5 | table access full | T2 | 57436 | 4431K | 161 (2) | 00:00:02 |
- Bytes ------------------------------------------------------------------------------------
- Predicate Information (identified by operation id ):
- ---------------------------------------------------
- 4-access ("T1". "OBJECT_ID" = "T2". "OBJECT_ID ")
- Filter ("T1". "OBJECT_ID" = "T2". "OBJECT_ID ")
- Note
- -----
- -Dynamic sampling used for this statement
- Statistics
- ----------------------------------------------------------
- 0 recursive cballs
- 0 db block gets
- 1396 consistent gets
- 0 physical reads
- 0 redo size
- 3166055 bytes sent via SQL * Net to client
- 37356 bytes encoded ed via SQL * Net from client
- 3363 SQL * Net roundtrips to/from client
- 2 sorts (memory)
- 0 sorts (disk)
- 50425 rows processed
- SQL> createindex ind_t1_object_id on t1 (object_id );
- The index has been created.
- SQL> createindex ind_t2_object_id on t2 (object_id );
- The index has been created.
- /** Because the index is ordered, sorting operations on external row sources can be eliminated */
- SQL> select/* + use_merge (t1, t2) + */t1.object _ id, t1.object _ name, t2.object _ name
- 2 from t1, t2
- 3 where t1.object _ id = t2.object _ id;
- Row 50425 has been selected.
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 3739185171
- Bytes ---------------------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | TempSpc | Cost (% CPU) | Time |
- Bytes ---------------------------------------------------------------------------------------------------------
- | 0 | select statement | 53430 | 8244K 4k | 2031 (1) | 00:00:25 |
- | 1 | merge join | 53430 | 8244K 4k | 2031 (1) | 00:00:25 |
- | 2 | table access byindex rowid | T2 | 57436 | 4431K | 879 (1) | 00:00:11 |
- | 3 | indexfull scan | IND_T2_OBJECT_ID | 57436 | 125 (2) | 00:00:02 |
- | * 4 | sort join | 53430 | 4122K | 9304K | 1152 (2) | 00:00:14 |
- | 5 | table access full | T1 | 53430 | 161 | (2) | 00:00:02 |
- Bytes ---------------------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id ):
- ---------------------------------------------------
- 4-access ("T1". "OBJECT_ID" = "T2". "OBJECT_ID ")
- Filter ("T1". "OBJECT_ID" = "T2". "OBJECT_ID ")
- Note
- -----
- -Dynamic sampling used for this statement
- Statistics
- ----------------------------------------------------------
- 8 recursive cballs
- 0 db block gets
- 8384 consistent gets
- 117 physical reads
- 0 redo size
- 3166055 bytes sent via SQL * Net to client
- 37356 bytes encoded ed via SQL * Net from client
- 3363 SQL * Net roundtrips to/from client
- 3 sorts (memory)
- 0 sorts (disk)
- 50425 rows processed
- SQL> select/* + use_merge (t1, t2) index (t1 ind_t1_object_id) + */t1.object _ id, t1.object _ name, t2.object _ name
- 2 from t1, t2
- 3 where t1.object _ id = t2.object _ id;
- Row 50425 has been selected.
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 3856170417
- Bytes ---------------------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | TempSpc | Cost (% CPU) | Time |
- Bytes ---------------------------------------------------------------------------------------------------------
- | 0 | select statement | 53430 | 8244K 4k | 2107 (1) | 00:00:26 |
- | 1 | merge join | 53430 | 8244K 4k | 2107 (1) | 00:00:26 |
- | 2 | table access byindex rowid | T1 | 53430 | 881 | (1) | 00:00:11 |
- | 3 | indexfull scan | IND_T1_OBJECT_ID | 53430 | 125 (2) | 00:00:02 |
- | * 4 | sort join | 57436 | 4431K | 9M | 1227 (2) | 00:00:15 |
- | 5 | table access full | T2 | 57436 | 4431K | 161 (2) | 00:00:02 |
- Bytes ---------------------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id ):
- ---------------------------------------------------
- 4-access ("T1". "OBJECT_ID" = "T2". "OBJECT_ID ")
- Filter ("T1". "OBJECT_ID" = "T2". "OBJECT_ID ")
- Note
- -----
- -Dynamic sampling used for this statement
- Statistics
- ----------------------------------------------------------
- 7 recursive cballs
- 0 db block gets
- 8386 consistent gets
- 0 physical reads
- 0 redo size
- 3166055 bytes sent via SQL * Net to client
- 37356 bytes encoded ed via SQL * Net from client
- 3363 SQL * Net roundtrips to/from client
- 3 sorts (memory)
- 0 sorts (disk)
- 50425 rows processed
- SQL> select/* + use_merge (t1, t2) index (t1 ind_t1_object_id) index (t2 ind_t2_object_id) + */t1.object _ id, t1.object _ name,
- 2. object_name
- 2 from t1, t2
- 3 where t1.object _ id = t2.object _ id;
- Row 50425 has been selected.
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 3655247094
- Bytes ----------------------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | TempSpc | Cost (% CPU) | Time |
- Bytes ----------------------------------------------------------------------------------------------------------
- | 0 | select statement | 53430 | 8244K 4k | 2750 (1) | 00:00:34 |
- | 1 | merge join | 53430 | 8244K 4k | 2750 (1) | 00:00:34 |
- | 2 | table access byindex rowid | T2 | 57436 | 4431K | 879 (1) | 00:00:11 |
- | 3 | indexfull scan | IND_T2_OBJECT_ID | 57436 | 125 (2) | 00:00:02 |
- | * 4 | sort join | 53430 | 4122K | 9304K | 1872 (1) | 00:00:23 |
- | 5 | table access byindex rowid | T1 | 53430 | 881 | (1) | 00:00:11 |
- | 6 | indexfull scan | IND_T1_OBJECT_ID | 53430 | 125 (2) | 00:00:02 |
- Bytes ----------------------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id ):
- ---------------------------------------------------
- 4-access ("T1". "OBJECT_ID" = "T2". "OBJECT_ID ")
- Filter ("T1". "OBJECT_ID" = "T2". "OBJECT_ID ")
- Note
- -----
- -Dynamic sampling used for this statement
- Statistics
- ----------------------------------------------------------
- 7 recursive cballs
- 0 db block gets
- 8551 consistent gets
- 0 physical reads
- 0 redo size
- 3166055 bytes sent via SQL * Net to client
- 37356 bytes encoded ed via SQL * Net from client
- 3363 SQL * Net roundtrips to/from client
- 3 sorts (memory)
- 0 sorts (disk)
- 50425 rows processed