您的位置:首页 > 数据库 > Oracle

【读书笔记】【收获,不止Oracle】不同连接类型表下,驱动顺序对查询性能的影响

2014-08-27 22:31 573 查看
本次试验用于探究 嵌套循环,哈希连接,排序合并这三种类型下,驱动表顺序的研究。

一、嵌套循环(Nested Loops Join)

1.t1为主表,t2为从表(t1表先访问)

select /*+leading(t1) use_nl(t2)*/*
from t1,t2
where t1.id = t2.t1_id
and t1.n = 19;
SCOTT@ orclselect * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  4j97842y306uk, child number 0
-------------------------------------
select /*+leading(t1) use_nl(t2)*/* from t1,t2 where t1.id = t2.t1_id and
t1.n = 19

Plan hash value: 1967407726

-------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------
|   1 |  NESTED LOOPS      |      |      1 |      1 |      1 |00:00:00.01 |    1014 |

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|*  2 |   TABLE ACCESS FULL| T1   |      1 |      1 |      1 |00:00:00.01 |       8 |
|*  3 |   TABLE ACCESS FULL| T2   |      1 |      1 |      1 |00:00:00.01 |    1006 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("T1"."N"=19)
   3 - filter("T1"."ID"="T2"."T1_ID")

Note

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----
   - dynamic sampling used for this statement

25 rows selected.



2.t1为从表,t2为主表时(t2表先访问)

select /*+leading(t2) use_nl(t1)*/*
from t1,t2
where t1.id = t2.t1_id
and t1.n = 19;

SCOTT@ orcl>select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  6uqqzgzs7y35f, child number 0
-------------------------------------
select /*+leading(t2) use_nl(t1)*/* from t1,t2 where t1.id = t2.t1_id and
t1.n = 19

Plan hash value: 4016936828

-------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------
|   1 |  NESTED LOOPS      |      |      1 |      1 |      1 |00:00:02.75 |     701K|

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   2 |   TABLE ACCESS FULL| T2   |      1 |    102K|    100K|00:00:00.30 |    1006 |
|*  3 |   TABLE ACCESS FULL| T1   |    100K|      1 |      1 |00:00:01.98 |     700K|
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - filter(("T1"."N"=19 AND "T1"."ID"="T2"."T1_ID"))

Note
-----

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- dynamic sampling used for this statement

24 rows selected.


3.结论:

StartsBuffers
第一次T1181014
T211006
第二次T211006701K
T1100K700k
3.1 根据驱动表的访问顺序不同,Buffers产生的差异是巨大的。

3.2 T1为驱动表时,T2被访问1次。而T2为驱动表时,T1被访问10000次。

3.3 循环嵌套表应注意驱动表的顺序。小的结果集先访问,大的结果集后访问。才能使得被驱动表的访问次数降到最低,从而提升性能。

二、哈希连接(Hash Join)

1.t1为主表,t2为从表(t1表先访问)

select /*+leading(t1) use_hash(t2)*/*
from t1,t2
where t1.id = t2.t1_id
and t1.n = 19;

SCOTT@ orcl>select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  c7tdkmk355c8n, child number 0
-------------------------------------
select /*+leading(t1) use_hash(t2)*/* from t1,t2 where t1.id = t2.t1_id and t1.n = 19

Plan hash value: 1838229974

----------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------
|*  1 |  HASH JOIN         |      |      1 |      1 |      1 |00:00:00.74 |    1013 |   741K|   741K|  328K (0)|
|*  2 |   TABLE ACCESS FULL| T1   |      1 |      1 |      1 |00:00:00.01 |       7 |       |       |          |

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   3 |   TABLE ACCESS FULL| T2   |      1 |    102K|    100K|00:00:00.20 |    1006 |       |       |          |
----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - access("T1"."ID"="T2"."T1_ID")
2 - filter("T1"."N"=19)

Note
-----

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- dynamic sampling used for this statement

24 rows selected.


2.t1为从表,t2为主表时(t2表先访问)

select /*+leading(t2) use_hash(t1)*/*
from t1,t2
where t1.id = t2.t1_id
and t1.n = 19;

SCOTT@ orcl>select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  5mszurvg6jrxx, child number 0
-------------------------------------
select /*+leading(t2) use_hash(t1)*/* from t1,t2 where t1.id = t2.t1_id and t1.n = 19

Plan hash value: 2959412835

----------------------------------------------------------------------------------------------------------------
| Id  | Operation          | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------
|*  1 |  HASH JOIN         |      |      1 |      1 |      1 |00:00:00.89 |    1013 |  9471K|  1956K|   10M (0)|
|   2 |   TABLE ACCESS FULL| T2   |      1 |    102K|    100K|00:00:00.20 |    1005 |       |       |          |

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|*  3 |   TABLE ACCESS FULL| T1   |      1 |      1 |      1 |00:00:00.01 |       8 |       |       |          |
----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - access("T1"."ID"="T2"."T1_ID")
3 - filter("T1"."N"=19)

Note
-----

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- dynamic sampling used for this statement

24 rows selected.


3.结论

StartsBuffersUsed-Mem
第一次T1171013328K
T211006
第二次T2102K1005101310M
T118
3.1 根据驱动表的访问顺序不同,Buffers相同,但Used-Mem的差别很大。

三、排序合并(Merge Sort Join)
1.t1为主表,t2为从表(t1表先访问)

select /*+leading(t1) use_merge(t2)*/*
from t1,t2
where t1.id = t2.t1_id
and t1.n = 19;

SCOTT@ orcl>select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  aw04dp4k1q1x7, child number 0
-------------------------------------
select /*+leading(t1) use_merge(t2)*/* from t1,t2 where t1.id = t2.t1_id and t1.n = 19

Plan hash value: 412793182

-----------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------
|   1 |  MERGE JOIN         |      |      1 |      1 |      1 |00:00:00.43 |    1012 |       |       |          |
|   2 |   SORT JOIN         |      |      1 |      1 |      1 |00:00:00.01 |       7 |  2048 |  2048 | 2048  (0)|

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|*  3 |    TABLE ACCESS FULL| T1   |      1 |      1 |      1 |00:00:00.01 |       7 |       |       |          |
|*  4 |   SORT JOIN         |      |      1 |    102K|      1 |00:00:00.43 |    1005 |  9124K|  1177K| 8110K (0)|
|   5 |    TABLE ACCESS FULL| T2   |      1 |    102K|    100K|00:00:00.20 |    1005 |       |       |          |
-----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

3 - filter("T1"."N"=19)
4 - access("T1"."ID"="T2"."T1_ID")
filter("T1"."ID"="T2"."T1_ID")

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Note
-----
- dynamic sampling used for this statement

27 rows selected.
2.t1为从表,t2为主表时(t2表先访问)

select /*+leading(t2) use_merge(t1)*/*
from t1,t2
where t1.id = t2.t1_id
and t1.n = 19;

SCOTT@ orcl>select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  79yag6bg8z2zr, child number 0
-------------------------------------
select /*+leading(t2) use_merge(t1)*/* from t1,t2 where t1.id = t2.t1_id and t1.n = 19

Plan hash value: 1792967693

-----------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------
|   1 |  MERGE JOIN         |      |      1 |      1 |      1 |00:00:00.86 |    1012 |       |       |          |
|   2 |   SORT JOIN         |      |      1 |    102K|     20 |00:00:00.86 |    1005 |  9124K|  1177K| 8110K (0)|

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   3 |    TABLE ACCESS FULL| T2   |      1 |    102K|    100K|00:00:00.20 |    1005 |       |       |          |
|*  4 |   SORT JOIN         |      |     20 |      1 |      1 |00:00:00.01 |       7 |  2048 |  2048 | 2048  (0)|
|*  5 |    TABLE ACCESS FULL| T1   |      1 |      1 |      1 |00:00:00.01 |       7 |       |       |          |
-----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

4 - access("T1"."ID"="T2"."T1_ID")
filter("T1"."ID"="T2"."T1_ID")
5 - filter("T1"."N"=19)

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Note
-----
- dynamic sampling used for this statement

27 rows selected.
3.结论

StartsBuffersUsed-Mem
第一次SORT1112048
SORT21102K8110
第二次SORT21102K8110
SORT1112048
3.1 无论t1先访问还是后访问Buffer,Status,Used-Mem都是一样的。所以排序合并下,驱动表的访问顺序无关。排序合并连接无驱动顺序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: