博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
嵌套循环连接(nested loops join)原理
阅读量:5058 次
发布时间:2019-06-12

本文共 4845 字,大约阅读时间需要 16 分钟。

 

嵌套循环连接(nested loops join)

   访问次数:驱动表返回几条,被驱动表访问多少次。

   驱动表是否有顺序:有。

   是否要排序:否。

   应用场景:  1.关联中有一个表比较小;

                            2.被关联表的关联字段上有索引;

                            3.索引的键值不应该重复率很高。

如果你做过开发,就把它看成两层嵌套的for循环。

下面我们来做个实验:

SQL> create table test1 as select * from dba_objects where rownum <=100;

SQL> create table test2 as select * from dba_objects where rownum <=1000;

SQL> exec dbms_stats.gather_table_stats(user,'test1');

SQL> exec dbms_stats.gather_table_stats(user,'test2');

SQL> alter session set statistics_level=all;

SQL> select /*+leading(t1) use_nl(t2)*/count(*)
  2    from test1 t1, test2 t2
  3   where t1.object_id = t2.object_id;
  COUNT(*)
----------
       100
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------
SQL_ID  3v5gu7ppdsz67, child number 0
-------------------------------------
select /*+leading(t1) use_nl(t2)*/count(*)   from test1 t1, test2 t2  where
t1.object_id = t2.object_id

Plan hash value: 1459699139

----解释一下:

Starts为该sql执行的次数。

E-Rows为执行计划预计的行数。

A-Rows为实际返回的行数。A-Rows跟E-Rows做比较,就可以确定哪一步执行计划出了问题。

A-Time为每一步实际执行的时间(HH:MM:SS.FF),根据这一行可以知道该sql耗时在了哪个地方。
Buffers为每一步实际执行的逻辑读或一致性读。
Reads为物理读。
OMem、1Mem为执行所需的内存评估值,0Mem为最优执行模式所需内存的评估值,1Mem为one-pass模式所需内存的评估值。
0/1/M 为最优/one-pass/multipass执行的次数。
Used-Mem耗的内存

 

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

| Id  | Operation           | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------
|   1 |  SORT AGGREGATE     |       |      1 |      1 |      1 |00:00:00.01 |    1504 |
|   2 |   NESTED LOOPS      |       |      1 |    100 |    100 |00:00:00.01 |    1504 |
|   3 |    TABLE ACCESS FULL| TEST1 |       1 |    100 |    100 |00:00:00.01 |       4 |
|*  4 |    TABLE ACCESS FULL| TEST2 |     100 |      1 |    100 |00:00:00.01 |    1500 |

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

Predicate Information (identified by operation id):

---------------------------------------------------
   4 - filter("T1"."OBJECT_ID"="T2"."OBJECT_ID")
SQL> select /*+leading(t1) use_nl(t2)*/count(*)
  2    from test1 t1, test2 t2
  3   where t1.object_id = t2.object_id
  4     and t1.object_id in (10, 11, 12);
  COUNT(*)
----------
         3
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------
SQL_ID  0skx6hyjtsncu, child number 0
-------------------------------------
select /*+leading(t1) use_nl(t2)*/count(*)   from test1 t1, test2 t2  where
t1.object_id = t2.object_id    and t1.object_id in (10, 11, 12)
---------------------------------------------------------------------------------------
| Id  | Operation           | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------
|   1 |  SORT AGGREGATE     |       |      1 |      1 |      1 |00:00:00.01 |      49 |
|   2 |   NESTED LOOPS      |       |      1 |      3 |      3 |00:00:00.01 |      49 |
|*  3 |    TABLE ACCESS FULL| TEST1 |       1 |      3 |      3 |00:00:00.01 |       4 |
|*  4 |    TABLE ACCESS FULL| TEST2 |       3 |      1 |      3 |00:00:00.01 |      45 |
---------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter(("T1"."OBJECT_ID"=10 OR "T1"."OBJECT_ID"=11 OR
              "T1"."OBJECT_ID"=12))
   4 - filter((INTERNAL_FUNCTION("T2"."OBJECT_ID") AND
              "T1"."OBJECT_ID"="T2"."OBJECT_ID"))
SQL> select /*+leading(t1) use_nl(t2)*/count(*)
  2    from test1 t1, test2 t2
  3   where t1.object_id = t2.object_id
  4     and t1.object_id =10;
  COUNT(*)
----------
         1
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------
SQL_ID  24g0zhvczyf2h, child number 0
-------------------------------------
select /*+leading(t1) use_nl(t2)*/count(*)   from test1 t1, test2 t2  where
t1.object_id = t2.object_id    and t1.object_id =10
Plan hash value: 1459699139
---------------------------------------------------------------------------------------
| Id  | Operation           | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------
|   1 |  SORT AGGREGATE     |       |      1 |      1 |      1 |00:00:00.01 |      19 |
|   2 |   NESTED LOOPS      |       |      1 |      1 |      1 |00:00:00.01 |      19 |
|*  3 |    TABLE ACCESS FULL| TEST1 |       1 |      1 |      1 |00:00:00.01 |       4 |
|*  4 |    TABLE ACCESS FULL| TEST2 |       1 |      1 |      1 |00:00:00.01 |      15 |
---------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter("T1"."OBJECT_ID"=10)
   4 - filter("T2"."OBJECT_ID"=10)

转载于:https://www.cnblogs.com/james1207/p/3400140.html

你可能感兴趣的文章
常见浏览器的兼容问题
查看>>
2018年最新Java面试题及答案整理
查看>>
DKNightVersion 的实现 --- 如何为 iOS 应用添加夜间模式
查看>>
es-多文档简单查询(_mget)
查看>>
Javascript 数组相关操作
查看>>
选择排序
查看>>
codevs 5462 HYY迎亲I
查看>>
类模板成员函数
查看>>
Dubbo
查看>>
并发计算/并行计算/串行计算/分布式计算 概念简述
查看>>
c#邮件发送
查看>>
debuggee python
查看>>
redis 从入门到遗忘
查看>>
构建之法阅读笔记02
查看>>
最简单实用的seo知识
查看>>
使用jmeter 进行http 接口测试
查看>>
编号001:deque用法暂时总结
查看>>
关于在Android中Activity页面跳转的方法
查看>>
GDAL数据模型
查看>>
[Python 网络编程] TCP编程/群聊服务端 (二)
查看>>