Oracle Table Connection

Source: Internet
Author: User

A plain statement select * from T1, t2 where t1.id = t2.id and t1.name = ' a '; Under what circumstances is this statement most efficient?

Table Connection Categories:

1. Nested loops connection (Nested loop join)

2. Sort Merge Connection (merge sort join): Sort_area_size control in the PGA

3. Hash connection (hash join): Hash_area_size control in the PGA

Examples (basically all performed in a sql*plus environment):

--Prepare the script

Prompt preparation of experimental environment .....

DROP TABLE t1 cascade constraints Purge;

DROP TABLE t2 cascade constraints Purge;

CREATE TABLE T1 (

ID number is not NULL,

N Number,

Contents VARCHAR2 (4000)

);

CREATE TABLE T2 (

ID number is not NULL,

T1_ID number is not NULL,

N Number,

Contents VARCHAR2 (4000)

);

Execute dbms_random.seed (0);

INSERT INTO T1

(

Id

N

Contents

)

Select RowNum,

RowNum

Dbms_random.string (' A ', 50)

From dual

Connect by Level <= 100

Order BY Dbms_random.random;

INSERT INTO T2

(

Id

T1_ID,

N

Contents

)

Select RowNum,

RowNum

RowNum

Dbms_random.string (' B ', 50)

From dual

Connect by Level <= 100000

Order BY Dbms_random.random;

Commit

--Modify statistical parameters to all

alter system set Statistics_level=all;

--ALTER session set Statistics_level=all; Session-level modification, occasional invalidation

Show parameter statistics_level;

Set Linesize 1000

--Experiment started

--NL junction table

--1.1 hint meaning leading (T1) means to force first access to the T1 table, which is the T1 table as the driver table; Use_nl means to force nested loops to join

Select/*+leading (T1) use_nl (T2) */* from T1, t2 where t1.id = t2.t1_id;

SELECT * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

Starts column is the number of table accesses, T1 table accessed 1 times, T2 table accessed 100 times

--1.2

Select/*+leading (T1) use_nl (T2) */* from T1, t2 where t1.id = t2.t1_id and T1.N in (19, 20);

SELECT * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

T1 table visited 1 times, T2 table visited 2 times

--1.3

Select/*+leading (T1) use_nl (T2) */* from T1, t2 where t1.id = t2.t1_id and T1.N = 19;

SELECT * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

T1 table visited 1 times, T2 table visited 1 times

--1.4

Select/*+leading (T1) use_nl (T2) */* from T1, t2 where t1.id = t2.t1_id and T1.N = 9999999;

SELECT * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

T1 table visited 1 times, T2 table visited 0 times

NL table Connection Access times the final conclusion: how many records are returned by the query for the T1 table, and how many times the T2 table is accessed. That is, in a nested loop connection, how many records the driver table returns and how many times the drive table is accessed.

--2. Hash join table

--2.1

Select/*+leading (T1) use_hash (T2) */* from T1, t2 where t1.id = t2.t1_id;

SELECT * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

T1 1 times, T2 1 times

In a hash connection, both the driver table and the driver table will only be accessed 1 or 0 times.

--2.2

Select/*+leading (T1) use_hash (T2) */* from T1, t2 where t1.id = t2.t1_id and T1.N = 9999999;

SELECT * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

T1 1 times, T2 0 times

--2.3

Select/*+leading (T1) use_hash (T2) */* from T1, t2 where t1.id = t2.t1_id and 1 = 2;

SELECT * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

T1 0 times, T2 0 times

--3. Sort Merge Connections

Select/*+ordered use_merge (T2) */* from T1, t2 where t1.id = t2.t1_id;

SELECT * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

T1 1 times, T2 1 times

Suppose that two tables, A and B, if a as a driver table, B as the driver table, then, the nested loop connection, is to scan a table first, a table of each record, scan the B table;

A sort merge connection is a table that is sorted with the records in table B and then connected; Hash joins, like sort merges, establish hash tables to connect. So when a small number of records are returned (OLTP systems are often used, OLTP is more useful for systems such as telecommunications, finance, etc.), nested loops are more efficient, and when a large number of records are returned, a sort merge connection is more efficient than a hash connection.

Different types of connection drive sequence differences

1. Nested loops Join

Select/*+leading (T1) use_nl (T2) */* from T1, t2 where t1.id = t2.t1_id and T1.N = 19;

Select/*+leading (T2) USE_NL (T1) */* from T1, t2 where t1.id = t2.t1_id and T1.N = 19;

SELECT * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

T1 Table First access: BUFFER 1014,t2 access only 1 times

T2 table First Accessed: BUFFER 701k,t1 was accessed 100,000 times

Therefore, nested loops join to pay special attention to the order of the driver tables, the small result set is first accessed, the large result set is accessed after

2. Hash connection

Select/*+leading (T1) use_hash (T2) */* from T1, t2 where t1.id = t2.t1_id and T1.N = 19;

Select/*+leading (T2) Use_hash (T1) */* from T1, t2 where t1.id = t2.t1_id and T1.N = 19;

SELECT * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

T1 Table First access: BUFFER 1013,used_mem 286K, time 0.04 seconds

T2 Table First Access: BUFFER 1013,used_mem 11MB, time 0.01 seconds

In a hash join, it is also important to drive the table order

3. Sort Merge Connections

Select/*+leading (T1) use_merge (T2) */* from T1, t2 where t1.id = t2.t1_id and T1.N = 19;

Select/*+leading (T2) use_merge (T1) */* from T1, t2 where t1.id = t2.t1_id and T1.N = 19;

SELECT * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

The same efficiency, execution time, Buffer,used_mem are the same regardless of whether you visit T1 first or T2 first, which indicates that the sort merge connection does not have a driver table concept.

In summary: Nested loops and Hash joins have a driving order, and the order of the driver tables will affect the performance of the table joins, whereas a sort merge connection has no driver concept, no matter which table is in front of it.

Nested loop joins do not require sorting, hash joins are not sorted, memory consumption is used to suggest hash tables; Sort merge joins need to be sorted. For hash joins and sort merge joins, do not take extra fields into the sort, because the fewer fields you select, the smaller the size of the memory that is consumed.

Select/*+leading (T2) use_merge (T1) */* from T1, t2 where t1.id = t2.t1_id and T1.N = 19;

Select/*+leading (T2) use_merge (t1) */t1.id from T1, t2 where t1.id = t2.t1_id and T1.N = 19;

SELECT * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

It can be seen that USED_MEM represents a significant difference in memory consumption.

Various connection limit Scenarios

Explain plan for

Select/*+leadind (T1) use_hash (T2) * *

from T1, T2

where T1.id <> t2.t1_id and T1.N = 19;

SELECT * FROM table (dbms_xplan.display);

Did not follow the instructions of hint to go hash connection, but walked the NL connection

Similarly, can be tested >, <, Like,hash are not supported.

Explain plan for

Select/*+leadind (T1) use_merge (T2) * *

from T1, T2

where T1.id <> t2.t1_id and T1.N = 19;

SELECT * FROM table (dbms_xplan.display);

Sort merge connections do not support <> and like, but support >, <

Nested Loops Unlimited

Table joins and indexes

Select/*+leading (T1) use_nl (T2) */* from T1, t2 where t1.id = t2.t1_id;

SELECT * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

If you do not use the hint hint

SELECT * from T1, t2 where t1.id = t2.t1_id;

SELECT * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

Will show a hash connection, because Oracle thinks the hash connection is more reasonable, but at this time the logical read, the cost value is similar

CREATE index t1_n on t1 (n);

Then execute the above statement to see the difference in buffer when scanning the T1 table.

Create index t2_t1_id on T2 (t1_id);

Then execute the above statement to see the difference in buffer when scanning the T2 table.

The most suitable scenario for the NL connection:

1. Two table associations return a small number of records, the best case is that the drive result set only returns 1 or a few records, and the driver table only matches to 1 or a few records, in this case, even if the records of the T1 and T2 tables are extremely large, it is very fast.

2. Encountering some non-equivalence queries that result in hash and sort merge connections being restricted, the NL connection has to be used.

3. The best index Establishment location: The driver table of the constraints of the column is indexed, the connection condition of the driver table is indexed. The reason for this is that the constraints on the driver table are indexed to reduce the time to scan the driver table, and if indexing on the connection condition of the driver table is meaningless, all columns are associated to all columns of the other table, equivalent to each record being associated. While the constraints of the driver table index, only quickly return 1 or a few, and then passed to the t1_id column of the T2 table, in general, T2 table corresponding T1 table returned records are not many, so T2 table t1_id column to build the index is meaningful.

Hash joins and indexes

The index of the join condition is not transitive for hash joins and sort merge joins, and for hash joins and sort merge joins, the index's join condition is not fast enough to retrieve, but it can improve performance if there are suitable indexes to quickly retrieve a small number of records.

Two tables associated with the equivalent query, Oracle generally tend to go hash connection, because the hash connection algorithm itself is more efficient, but also more advanced. The optimized hash connection can be optimized by adjusting the hash_area_size in the PGA, which increases the PGA size if the PGA is automatically managed.

Sort merge joins and indexes

The join conditions on a sort merge connection are not retrievable, but have the effect of eliminating sorting, thus improving efficiency.

Sql>select/*+ordered Use_merge (T2) */

*

from T1, T2

where t1.id = t2.t1_id;

Sql>select * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

CREATE index IDX_T1 on T1 (ID);

Create index idx_t1_id on T2 (t1_id); --Built above

Sql>select/*+ordered Use_merge (T2) */

*

from T1, T2

where t1.id = t2.t1_id;

Sql>select * FROM table (dbms_xplan.display_cursor (null, NULL, ' Allstats last '));

Two indexes were built, eventually using only one, which is the Oracle sort merge connection bug, which is acknowledged in the 11G official document.

You can also optimize the sort merge connection by increasing the PGA

Oracle Table Connection

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.