35.读书笔记收获不止Oracle之嵌套循环表连接与索引

35.读书笔记收获不止Oracle之嵌套循环表连接与索引

                  表连接的研究中,索引是非常重要的一部分,对提升表连接性能起到至关重要的作用。

1.  嵌套循环与索引

SQL>alter session set statistics_level=all;

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

SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstatslast'));

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

SQL_ID   2w8kmgu3tmxhq,child number 0

-------------------------------------

select /*+leading(t1) use_nl(t2)*/ * fromt1,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   | Buff

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

ers |

 

--------------------------------------------------------------------------------

-----

 

|   0| SELECT STATEMENT   |      |           1 |              |         1 |00:00:00.01 |    1

014 |

 

|   1|  NESTED LOOPS     |          |           1 |            1 |          1 |00:00:00.01 |    1

014 |

 

 

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 |    1

006 |

 

--------------------------------------------------------------------------------

-----

 

 

Predicate Information (identified byoperation id):

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

---------------------------------------------------

 

   2- filter("T1"."N"=19)

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

 

 

22 rows selected.

1.1      不用HINT

SQL>select * from t1,t2 where t1.id=t2.t1_id and t1.n=19;

SQL> select * fromtable(dbms_xplan.display_cursor(null,null,'allstats last'));

--------------------------------------------------------------------------------

SQL_ID   g7rb3y8bmguur,child number 0

-------------------------------------

select * from t1,t2 where t1.id=t2.t1_idand t1.n=19

 

Plan hash value: 1838229974

 

--------------------------------------------------------------------------------

--------------------------------

 

| Id | Operation                     | Name | Starts | E-Rows | A-Rows |         A-Time   | Buff

ers | OMem |  1Mem | Used-Mem |

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

 

--------------------------------------------------------------------------------

--------------------------------

 

|   0| SELECT STATEMENT   |      |           1 |              |         1 |00:00:00.06 |    1

013 |           |          |             |

 

|*  1|  HASH JOIN              |         |           1 |           1 |          1 |00:00:00.06 |    1

013 |       960K|      960K| 385K (0)|

 

|*  2|   TABLE ACCESS FULL| T1   |         1 |            1 |          1 |00:00:00.01 |

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

  7 |          |          |             |

 

|   3|   TABLE ACCESS FULL| T2   |         1 |          100K|      100K|00:00:00.01 |    1

006 |           |          |             |

 

--------------------------------------------------------------------------------

--------------------------------

 

 

Predicate Information (identified byoperation id):

---------------------------------------------------

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

 

   1- access("T1"."ID"="T2"."T1_ID")

   2- filter("T1"."N"=19)

 

 

21 rows selected.

没有HINT,就走Hash Join。其实两者的消耗应该是差不多的。

 

1.2      T1表键索引后

SQL>create index t1_n on t1(n);

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

 

SQL> select * fromtable(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

SQL_ID   4n9w3nnj61xk0,child number 0

-------------------------------------

 select /*+leading(t1) use_nl(t2)*/ * fromt1,t2 where t1.id=t2.t1_id

and t1.n=19

 

Plan hash value: 2987075831

 

--------------------------------------------------------------------------------

-----------------------

 

| Id | Operation                                                           | Name | Starts | E-Rows | A-Rows |

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

  A-Time   | Buffers |

 

--------------------------------------------------------------------------------

-----------------------

 

|   0| SELECT STATEMENT                                     |       |         1 |           |     1 |

00:00:00.01 |        1009 |

 

|   1|  NESTED LOOPS                                           |       |         1 |         1 |     1 |

00:00:00.01 |        1009 |

 

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

|   2|   TABLE ACCESS BY INDEX ROWID BATCHED|T1   |                     1 |         1 |     1 |

00:00:00.01 |            3 |

 

|*  3|    INDEX RANGE SCAN                              | T1_N |         1 |         1 |     1 |

00:00:00.01 |            2 |

 

|*  4|   TABLE ACCESS FULL                                | T2  |        1 |         1 |     1 |

00:00:00.01 |        1006 |

 

--------------------------------------------------------------------------------

-----------------------

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

 

 

Predicate Information (identified byoperation id):

---------------------------------------------------

 

   3- access("T1"."N"=19)

   4- filter("T1"."ID"="T2"."T1_ID")

 

 

23 rows selected.

 

22 rows selected.

T1表走的是索引了。

1.3      T2表建索引

SQL>create index t2_t1_id on t2(t1_id);

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

SQL> select * fromtable(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

SQL_ID   2w8kmgu3tmxhq,child number 0

-------------------------------------

select /*+leading(t1) use_nl(t2)*/ * fromt1,t2 where t1.id=t2.t1_id

and t1.n=19

 

Plan hash value: 342856344

 

--------------------------------------------------------------------------------

-------------------------------------

 

| Id | Operation                                                            | Name      | Starts | E-Rows | A-R

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

ows |       A-Time    | Buffers | Reads  |

 

--------------------------------------------------------------------------------

-------------------------------------

 

|   0| SELECT STATEMENT                                      |                  |             1|               |

  1|00:00:00.03 |               7 |           4 |

 

|   1|  NESTED LOOPS                                            |                  |             1|            1 |

  1|00:00:00.03 |               7 |           4 |

 

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

|   2|   NESTED LOOPS                                                            |                  |             1|            1 |

  1|00:00:00.03 |               6 |           4 |

 

|   3|    TABLE ACCESS BY INDEX ROWID BATCHED|T1       |             1 |            1 |

  1|00:00:00.01 |               3 |           0 |

 

|*  4|     INDEX RANGE SCAN                            | T1_N       |             1 |            1 |

  1|00:00:00.01 |               2 |           0 |

 

|*  5|    INDEX RANGE SCAN                               | T2_T1_ID |             1 |            1 |

  1|00:00:00.03 |               3 |           4 |

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

 

|   6|   TABLE ACCESS BY INDEX ROWID        |T2             |             1 |            1 |

  1|00:00:00.01 |               1 |           0 |

 

--------------------------------------------------------------------------------

-------------------------------------

 

 

Predicate Information (identified byoperation id):

---------------------------------------------------

 

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

   4- access("T1"."N"=19)

   5- access("T1"."ID"="T2"."T1_ID")

25 rows selected.

T2表也走索引了。现在不用HINT,ORACLE也会自己走索引了,因为代价已经很低了。

如下:

SQL>select * from t1,t2 where t1.id=t2.t1_id and t1.n=19;

SQL> select * fromtable(dbms_xplan.display_cursor(null,null,'allstats last'));

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

SQL_ID   g7rb3y8bmguur,child number 0

-------------------------------------

select * from t1,t2 where t1.id=t2.t1_idand t1.n=19

 

Plan hash value: 342856344

 

--------------------------------------------------------------------------------

----------------------------

 

| Id | Operation                                                            | Name      | Starts | E-Rows | A-R

ows |       A-Time    | Buffers |

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

 

--------------------------------------------------------------------------------

----------------------------

 

|   0| SELECT STATEMENT                                      |                  |             1|               |

  1|00:00:00.01 |               6 |

 

|   1|  NESTED LOOPS                                            |                  |             1|            1 |

  1|00:00:00.01 |               6 |

 

|   2|   NESTED LOOPS                                                            |                  |             1|            1 |

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

  1|00:00:00.01 |               5 |

 

|   3|    TABLE ACCESS BY INDEX ROWID BATCHED|T1       |             1 |            1 |

  1|00:00:00.01 |               2 |

 

|*  4|     INDEX RANGE SCAN                            | T1_N       |             1 |            1 |

  1|00:00:00.01 |               1 |

 

|*  5|    INDEX RANGE SCAN                               | T2_T1_ID |             1 |            1 |

  1|00:00:00.01 |               3 |

 

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

|   6|   TABLE ACCESS BY INDEX ROWID        |T2             |             1 |            1 |

  1|00:00:00.01 |               1 |

 

--------------------------------------------------------------------------------

----------------------------

 

 

Predicate Information (identified byoperation id):

---------------------------------------------------

 

   4- access("T1"."N"=19)

 

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

   5- access("T1"."ID"="T2"."T1_ID")

 

Note

-----

   -this is an adaptive plan

28 rows selected.

2.  最实用NL连接的场景

两表关联返回的记录不多。

遇到一些不等值查询,只能试用NL连接。

当然最好:驱动表的限制条件所在的列有索引,被驱动表的连接条件所在的列也有索引。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值