Oracle 多表 连接 顺序 与 性能关系 测试

 

. 创建表并insert 数据

create table ta (id number,name varchar2(10));

create table tb(id number,job varchar2(10));

 

begin

for i in 1..1000000 loop

begin

insert into ta values(i,'dave');

commit;

end;

end loop;

end;

 

begin

for i in 1..1000000 loop

begin

if i<10 then

insert into tb values(i,'boy');

elsif i<20 and i>10 then

insert into tb values(i,'girl');

commit;

end if;

end;

end loop;

end;

 

.在没有索引的情况关联ta tb 查询

 

相关链接:

       Oracle Optimizer CBO RBO

       http://blog.csdn.net/tianlesoftware/archive/2010/08/19/5824886.aspx

 

       多表连接的三种方式详解 HASH JOIN MERGE JOIN NESTED LOOP

       http://blog.csdn.net/tianlesoftware/archive/2010/08/21/5826546.aspx

 

       Oracle Hint

       http://blog.csdn.net/tianlesoftware/archive/2010/08/23/5833020.aspx

 

2.1  optimizer选择 CBO10g 默认)

--ta 在前

select ta.id, ta.name,tb.job from ta,tb where ta.id=tb.id;

 

 

--tb 在前

select ta.id, ta.name,tb.job from tb,ta where ta.id=tb.id;

 

总结:    

       两条SQL 执行计划是一样的, tatb 的顺序没有影响。

       因为tatb 的记录相差较大,ta100万,tb 只有20条。 所以这里CBO 选择使用Hash Join

       CBO 选择2个表中记录较小的表tb,将其数据放入内存,对Join key构造hash 表,然后去扫描大表ta 找出与散列表匹配的行。

 

2.2 tatb ID b-tree 索引后在查看

 

--建索引

create index idx_ta_id on ta(id);

create index idx_tb_id on tb(id);

 

--tb 在前

select ta.id, ta.name,tb.job from tb,ta where ta.id=tb.id;

 

 

--ta 在前

select ta.id, ta.name,tb.job from ta,tb where ta.id=tb.id;

 

总结:

       执行计划还是一样,不同的是表之间的关联模式发生的改变,从Hash Join 变成了Nested Loops

       Nested loop一般用在连接的表中有索引,并且索引选择性较好的时候. 在我们这个示例中,CBO 选择把返回结果集较小的表tb 作为outer tableCBO 下,默认把outer table 作为驱动表,然后用outer table 的每一行与inner table(我们这里是ta)进行Join,去匹配结果集。 由此可见,在tbinner table 有索引的情况,这种匹配就非常快。

 

       这种情况下整个SQLcost

       cost = outer access cost + (inner access cost * outer cardinality)

 

       从某种角度上看,可以把Nested loop 看成2for 循环。

 

 

2.3 使用RBO 查看

       10g里,optimizer 默认已经使用CBO了,如果我们想使用RBO 只能通过Hint 来实现。

      

-- ta 在前

select /*+rule*/ta.id, ta.name,tb.job from ta,tb where ta.id=tb.id;

 

 

SYS@anqing2(rac2)> select /*+rule*/ta.id, ta.name,tb.job from ta,tb where ta.id<100 and  ta.id=tb.id;

Elapsed: 00:00:00.00

-- 注意这个SQL里,我们加了ta.id<100 的条件

Execution Plan

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

Plan hash value: 3943212106

 

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

| Id  | Operation                     | Name      |

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

|   0 | SELECT STATEMENT              |           |

|   1 |  TABLE ACCESS BY INDEX ROWID  | TB        |

|   2 |   NESTED LOOPS                |           |

|   3 |    TABLE ACCESS BY INDEX ROWID| TA        |

|*  4 |     INDEX RANGE SCAN          | IDX_TA_ID |

|*  5 |    INDEX RANGE SCAN           | IDX_TB_ID |

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

-- 当我们加上条件之后,就先走ta了,而不是tb 因为先走ta,用ta的限制条件过滤掉一部分结果,这样剩下的匹配工作就会减少。

Predicate Information (identified by operation id):

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

 

   4 - access("TA"."ID"<100)

   5 - access("TA"."ID"="TB"."ID")

 

Note

-----

   - rule based optimizer used (consider using cbo)

 

--tb 在前

select /*+rule*/ta.id, ta.name,tb.job from tb,ta where ta.id=tb.id;

 

 

 

总结:

       2个就区别很明显。 因为Oraclesql的解析是从后向前的。 那么当先遇到tb时,那么会对tb进行全表扫描,然后用这个结果匹配ta。因为ta有索引,所以通过索引去匹配。

       如果先遇到ta,那么就会对ta进行全表扫描。 因为2个表的差距很大,所以全表扫描的成本也就很大。

       所以在RBO 下,大表在前,小表在后。这样就会先遇到小表,后遇到大表。 如果有指定限定的where 条件,会先走限定条件的表。

 

 

2.4 drop 索引之后,在走RBO

 

drop index idx_ta_id;

drop index idx_tb_id;

 

 

--ta 在前

select /*+rule*/ta.id, ta.name,tb.job from ta,tb where ta.id=tb.id;

--tb 在前

select /*+rule*/ta.id, ta.name,tb.job from tb,ta where ta.id=tb.id;

 

总结:

       这里选择了Sort Merge Join 来连接2张表。Sort Merge join 用在没有索引,并且数据已经排序的情况.

      

       我们表中的记录是按照顺序插叙的,所以符合这个条件。 SQL 的解析还是按照从后往前,所以这里tatb 在前先扫描的顺序不一样,不过都是全表扫描。 效率都不高。

 

 

2.5  引深一个问题:使用 字段名 代替 *

       * 能方便很多,但在ORACLE解析的过程中, 会通过查询数据字典,会将’*’ 依次转换成所有的列名,这就需要耗费更多的时间. 从而降低了效率。

 

SYS@anqing2(rac2)> set timing on

SYS@anqing2(rac2)> select * from ta where rownum=1;

        ID NAME

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

         1 dave

 

Elapsed: 00:00:00.03

SYS@anqing2(rac2)> desc ta

 Name                 Null?    Type

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

 ID                           NUMBER

 NAME                       VARCHAR2(10)

 

SYS@anqing2(rac2)> select id,name from ta where rownum=1;

 

        ID NAME

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

         1 dave

 

Elapsed: 00:00:00.02

                                     

时间已经缩短。 但不明显,用Toad 来查看一下:

 

写全字段,执行时间是161 毫秒,用* 561毫秒。 差距很明显。

 

查看一下他们的执行计划:

SYS@anqing2(rac2)> select * from ta where rownum=1;

Elapsed: 00:00:00.00

 

Execution Plan

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

Plan hash value: 761731071

 

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

| id  | operation          | name | rows  | bytes | cost (%cpu)| time     |

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

|   0 | select statement   |      |     1 |    20 |     7  (72)| 00:00:01 |

|*  1 |  count stopkey   |      |       |      |           |         |

|   2 |   table access full| ta   |   890k|    16m|     7  (72)| 00:00:01 |

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

 

Predicate Information (identified by operation id):

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

 

   1 - filter(ROWNUM=1)

 

Note

-----

   - dynamic sampling used for this statement

 

SYS@anqing2(rac2)> select id,name from ta where rownum=1;

Elapsed: 00:00:00.00

Execution Plan

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

Plan hash value: 761731071

 

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

| id  | operation          | name | rows  | bytes | cost (%cpu)| time     |

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

|   0 | select statement   |      |     1 |    20 |     7  (72)| 00:00:01 |

|*  1 |  count stopkey   |      |       |      |           |        |

|   2 |   table access full| ta   |   890k|    16m|     7  (72)| 00:00:01 |

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

 

Predicate Information (identified by operation id):

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

 

   1 - filter(ROWNUM=1)

 

Note

-----

   - dynamic sampling used for this statement

 

 

注意:

       使用 * 和 写全字段名,他们的执行计划是一样的,但是执行时间不一样。

 

 

 

 

 

 

 

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

Blog http://blog.csdn.net/tianlesoftware

Email: dvd.dba@gmail.com

DBA1 群:62697716();   DBA2 群:62697977()   DBA3 群:62697850()  

DBA 超级群:63306533();  DBA4 群: 83829929  DBA5群: 142216823   

DBA6 群:158654907  聊天 群:40132017   聊天2群:69087192

--加群需要在备注说明Oracle表空间和数据文件的关系,否则拒绝申请

转载于:https://www.cnblogs.com/zlja/archive/2011/06/16/2449636.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/475597.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

线性规划 - 用单纯形法解决LP问题 - (Matlab、Lingo建模)

线性规划研究时间较早&#xff0c;在实际应用中也比较成熟&#xff0c;它是一种辅助人们进行科学管理的数学方法&#xff0c;为合理地利用有限的人力、物力、财力等资源作出的最优决策&#xff0c;提供科学的依据。 课题名称&#xff1a;配货问题&#xff0c;使运费收入最大 现…

微软Webcast课程下载软件iReaper正式登陆Android平台

微软Webcast课程下载软件iReaper正式登陆Android平台&#xff0c;我叫它iReaper for Android。目前正处于测试阶段&#xff0c;功能比较单一。 目前支持 1.视频下载 2.课程代码下载 3.讲义下载 4.问答下载 附上截图&#xff0c;敬请期待&#xff01; 1.下载地址&#xff…

动态规划 - Floyd算法求最短路径 - (Matlab建模)

Floyd算法又称为弗洛伊德算法、插点法&#xff0c;是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法&#xff0c;与Dijkstra算法类似。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特弗洛伊德命名。 课题名称&#xff1a;…

神经网络 - BP神经网络与RBF神经网络模型解决实际问题 - (Matlab建模)

目录 神经网络模型简述 实例&#xff1a;交通运输能力预测设计 MATLAB程序及仿真结果 由于货物运输、地方经济及企业发展的紧密联系&#xff0c;因此作为反映货物运输需求的一项重要指标, 货运量预测研究和分析具有较强的实际意义。 常用的货运量预测方法包括时间序列方法、…

LeetCode 135. 分发糖果(DP)

1. 题目 老师想给孩子们分发糖果&#xff0c;有 N 个孩子站成了一条直线&#xff0c;老师会根据每个孩子的表现&#xff0c;预先给他们评分。 你需要按照以下要求&#xff0c;帮助老师给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。相邻的孩子中&#xff0c…

网络数据的背后-网络日志的分析指标【转】

通常网站分析的技术包括页面标签分析技术&#xff08;JS技术&#xff09;和日志文件分析技术两种&#xff0c;两种网站分析技术各有优缺点&#xff0c;譬如下文中介绍的基于回话的统计和点击流分析日志文件分析法就要优于页面标签分析法&#xff0c;通常&#xff0c;两种技术具…

词云图 - WorldCloud - Python代码实现

目录 第一步&#xff1a;安装必要的包WorldCloud&#xff08;安装好并且没有出错的可跳过这一步&#xff09; 第二步&#xff1a;准备文件&#xff0c;词云图的图片和文章&#xff0c;按照自己喜好准备吧 第三步&#xff1a;Python实现-源码 第一步&#xff1a;安装必要的包…

[Hands On ML] 2. 一个完整的机器学习项目(加州房价预测)

文章目录1. 项目介绍2. 性能指标3. 确定任务类型4. 查看数据5. 创建测试集6. 数据可视化7. 查找数据关联8. 特征组合9. 为算法准备数据9.1 数据清洗9.2 处理文本特征10. 自定义转换器11. 特征缩放12. 转换流水线Pipeline13. 训练模型14. 交叉验证15. 微调模型15.1 网格搜索15.2…

线性回归 - 机器学习多元线性回归 - 一步一步详解 - Python代码实现

目录 数据导入 单变量线性回归 绘制散点图 相关系数R 拆分训练集和测试集 多变量线性回归 数据检验&#xff08;判断是否可以做线性回归&#xff09; 训练线性回归模型 先甩几个典型的线性回归的模型&#xff0c;帮助大家捡起那些年被忘记的数学。 ● 单变量线性回归&…

聚类分析 - K-means - Python代码实现

算法简介 K-means算法是很典型的基于距离的聚类算法&#xff0c;采用距离作为相似性的评价指标&#xff0c;即认为两个对象的距离越近&#xff0c;其相似度就越大。该算法认为簇是由距离靠近的对象组成的&#xff0c;因此把得到紧凑且独立的簇作为最终目标。 算法过程如下&…

数据归一化 - MinMaxScaler()/MaxAbsScaler() - Python代码

目录 归一化 数据归一化的背景介绍 MinMaxScaler&#xff1a;归一到 [ 0&#xff0c;1 ] MaxAbsScaler&#xff1a;归一到 [ -1&#xff0c;1 ] 标准化 去均值&#xff0c;方差规模化 归一化 数据归一化的背景介绍 在之前做聚类分析的时候我们发现&#xff0c;聚类的…

loadrunner 配置远程监控windows服务器系统资源

今天决定监控远程windows xp上的系统资源&#xff0c;本来以为应该很好连接&#xff0c;在同一个局域网内&#xff0c;结果出了一堆问题&#xff0c;可能是第一次就让我遇到了一个棘手的操作系统&#xff0c;郁闷&#xff01; &#xff08;1&#xff09;保证装有loadrunner的测…

Python数据清洗 - 洗什么?怎么洗?看完就明白了

目录 缺失值处理 删除缺失值 插补缺失值 不处理缺失值 重复值处理 异常值处理 遍历查找异常值&#xff0c;并根据规则调整大小 删除异常值 视为缺失值后进行插补 数据挖掘过程中&#xff0c;采集的原始数据里存在着各种不利于分析与建模工作的因素&#xff0c;比如数…

LeetCode 743. 网络延迟时间(最短路径)

文章目录1. 题目2. 解题2.1 弗洛伊德1. 题目 有 N 个网络节点&#xff0c;标记为 1 到 N。 给定一个列表 times&#xff0c;表示信号经过有向边的传递时间。 times[i] (u, v, w)&#xff0c;其中 u 是源节点&#xff0c;v 是目标节点&#xff0c; w 是一个信号从源节点传递到…

逻辑回归 - sklearn (LR、LRCV、MLP、RLR)- Python代码实现

目录 LR&#xff08;LogisticRegression&#xff09; - 线性回归 LRCV&#xff08;LogisticRegressionCV &#xff09;- 逻辑回归 MLP&#xff08;MLPRegressor&#xff09; - 人工神经网络 RLR&#xff08;RandomizedLogisticRegression&#xff09;-随机逻辑回归 logisti…

轻松看懂机器学习十大常用算法 - 基础知识

通过本篇文章可以对机器学习ML的常用算法有个常识性的认识&#xff0c;没有代码&#xff0c;没有复杂的理论推导&#xff0c;就是图解一下&#xff0c;知道这些算法是什么&#xff0c;它们是怎么应用的&#xff0c;例子主要是分类问题。 算法如下&#xff1a; 决策树随机森林算…

数据离散化 - 等宽等频聚类离散 - Python代码

目录 等宽离散 等频离散 聚类离散 附录&#xff1a; rolling_mean函数解释 cut函数解释 其他数据预处理方法 一些数据挖掘算法中&#xff0c;特别是某些分类算法&#xff08;eg:ID3算法、Aprioroi算法等&#xff09;&#xff0c;要求数据是分类属性形式。因此常常需要将…

LeetCode 1444. 切披萨的方案数(DP)

1. 题目 给你一个 rows x cols 大小的矩形披萨和一个整数 k &#xff0c;矩形包含两种字符&#xff1a; ‘A’ &#xff08;表示苹果&#xff09;和 ‘.’ &#xff08;表示空白格子&#xff09;。 你需要切披萨 k-1 次&#xff0c;得到 k 块披萨并送给别人。 切披萨的每一刀…

获取数据 - 将Excel文件读入矩阵matrix中 - Python代码

机器学习中&#xff0c;很多算法的计算逻辑是基于数学的&#xff0c;免不了求特征值和特征向量这种事情&#xff0c;因此&#xff0c;在数据预处理的时候&#xff0c;将数据源中的数据转储成矩阵格式是很有必要的。 原数据&#xff1a; 代码&#xff1a; import numpy as np…

Visual Studio 2010 调试 C 语言程序

转&#xff1a;http://woyouxian.net/c/using_visual_studio_write_pure_ansi_c_program.html 本篇文章讲述如何用微软的 Visual Studio 编写纯C语言程序&#xff0c;这里的纯C语言&#xff0c;指的是 ANSI C 语言。 要在 Visual Studio 里创建一个 ANSI C语言程序&#xff0c;…