- 浏览: 559125 次
- 性别:
- 来自: 北京
最新评论
-
anqinghaozi:
请问 你这weblogic jms 如何部署到tomcat上去 ...
Spring+weblogic接收JMS消息 -
cjliang:
1456746014@qq.com 我也要
jqGrid学习 ----------------- 第一个实例 -
Moy_Yeung:
Moy_Yeung 写道 您好 我最近在学习使用这个插件 能麻 ...
jqGrid学习 ----------------- 第一个实例 -
Moy_Yeung:
您好 我最近在学习使用这个插件 能麻烦博主发份demo吗 谢 ...
jqGrid学习 ----------------- 第一个实例 -
十叶木竹:
最近在自学这个插件,麻烦博主,发一份源码,以供学习,谢谢博主啦 ...
jqGrid学习 ----------------- 第一个实例
一般情况下,nested loop驱动行源应该选择小表,或者行数少的行源,但有时候也不一定。我们来看一个使用大表做驱动行源的例子。
1. 创建测试环境
大表test_big,小表test_small,二者通过test_big.object_id=test_small.object_id来关联。其中大表的object_id中会有重复记录,而小表中的object_id是唯一的,两个列上都有索引。
C:\Documents and Settings\yuechao.tianyc>sqlplus test/test
SQL*Plus: Release 10.2.0.1.0 - Production on 星期日 3月 29 22:37:13 2009
Copyright (c) 1982, 2005, Oracle. All rights reserved.
连接到:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> create table test_big as select * from dba_objects;
表已创建。
SQL> insert into test_big select * from test_big;
已创建50000行。
SQL> /
已创建100000行。
...
SQL> /
已创建6400000行。
SQL> commit;
提交完成。
SQL> create table test_small as select * from dba_objects where rownum < 5001;
表已创建。
SQL> create index ind_test_big on test_big(object_id);
索引已创建。
SQL> create index ind_test_small on test_small(object_id);
索引已创建。
2. 获取执行计划
分别使用大表和小表作为驱动行源,先看一下它们的执行计划:
-- 1. 使用test_big作为驱动行源
-- 执行步骤:(1)全表扫描test_big,得到行源A;(2)将A作为驱动行源,嵌套循环连接索引ind_test_small,得到行源B;(3)将行源B通过索引ind_test_small与表test_small关联,得到结果集。
SQL> explain plan for
2 select/*+ordered use_nl(test_big,test_small)*/ count(test_big.object_name||test_small.object_name)
3 from test_big, test_small where test_big.object_id = test_small.object_id;
已解释。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
Plan hash value: 3591390207
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 158 | 15M (1)| 53:19:22 |
| 1 | SORT AGGREGATE | | 1 | 158 | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEST_SMALL | 1 | 79 | 2 (0)| 00:00:01 |
| 3 | NESTED LOOPS | | 1247K| 187M| 15M (1)| 53:19:22 |
| 4 | TABLE ACCESS FULL | TEST_BIG | 14M| 1106M| 39134 (2)| 00:07:50 |
|* 5 | INDEX RANGE SCAN | IND_TEST_SMALL | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("test_big"."OBJECT_ID"="test_small"."OBJECT_ID")
Note
-----
- dynamic sampling used for this statement
已选择21行。
-- 2. 使用test_small作为驱动行源
-- 执行步骤:(1)全表扫描test_small,得到行源A;(2)将A作为驱动行源,嵌套循环连接索引ind_test_big,得到行源B;(3)将行源B通过索引ind_test_big与表test_big关联,得到结果集。
SQL> explain plan for
2 select/*+ordered use_nl(test_big,test_small)*/ count(test_big.object_name||test_small.object_name)
3 from test_small, test_big where test_big.object_id = test_small.object_id;
已解释。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
Plan hash value: 1952886871
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 158 | 1098K (1)| 03:39:42 |
| 1 | SORT AGGREGATE | | 1 | 158 | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEST_BIG | 257 | 20303 | 226 (0)| 00:00:03 |
| 3 | NESTED LOOPS | | 1247K| 187M| 1098K (1)| 03:39:42 |
| 4 | TABLE ACCESS FULL | TEST_SMALL | 4854 | 374K| 17 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | IND_TEST_BIG | 257 | | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("test_big"."OBJECT_ID"="test_small"."OBJECT_ID")
Note
-----
- dynamic sampling used for this statement
已选择21行。
3. 比较执行时间
比较上面两个不同的执行计划。看起来使用表test_small作为驱动行源更合理一些,它只有50001行,而表test_big有12800000行数据。而实际却不是这样,我们看一下他们各自的执行时间:
SQL> set timing on
-- 使用大表作为驱动行源
SQL> select/*+ordered use_nl(test_big,test_small)*/ count(test_big.object_name||test_small.object_name)
2 from test_big, test_small where test_big.object_id = test_small.object_id;
COUNT(TEST1.OBJECT_NAME||TEST2.OBJECT_NAME)
-------------------------------------------
12800000
已用时间: 00: 00: 36.70
-- 使用小表作为驱动行源
SQL> select/*+ordered use_nl(test1,test2)*/ count(test1.object_name||test2.object_name)
2 from test2, test1 where test1.object_id = test2.object_id;
COUNT(TEST1.OBJECT_NAME||TEST2.OBJECT_NAME)
-------------------------------------------
12800000
已用时间: 00: 02: 42.89
我们看到,使用大表作为驱动行源,耗时约36.7秒;而使用小表作为驱动行源,耗时达到2分42.89秒!
4. 原因
其实原因就在与大表的列object_id中有很多重复记录,当使用小表作为驱动行源时,全表扫描test_small的时间虽然很快,但对于test_small中的每一条记录,都对应test_big中的若干条记录,那么就需要根据查到的这些rowid,进行若干次的磁盘I/O来获得大表对应的数据。这里频繁的磁盘I/O就是问题的原因。因为test_big数据量很大,数据不可能存储在内存中。
而当使用大表作为驱动行源时,全表扫描test_big的时间虽然比较长,但每条记录都对应test_small中的一条记录,而且表test_small比较小,其数据及索引数据可以从内存中直接找到。这样耗费的时间就主要是全表扫描test_big的时间了,而这耗费不了太多的时间。在下面的测试中,只耗费了26.14秒:
SQL> select count(*) from test_big;
COUNT(*)
----------
12800000
已用时间: 00: 00: 26.14
SQL> set timing off
SQL> explain plan for
2 select count(*) from test_big;
已解释。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------
--------------------------------------------------------------------------
Plan hash value: 3224830981
-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 38982 (2)| 00:07:48 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| TEST_BIG | 14M| 38982 (2)| 00:07:48 |
-----------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement
已选择13行。
5. 备注
这里只是一个小测试,来说明nested loop中,驱动行源的选择要根据实际情况而定,不是一成不变的。其实这个SQL使用hash join是最快的:
SQL> explain plan for
2 select count(test_big.object_name||test_small.object_name)
3 from test_big, test_small where test_big.object_id = test_small.object_id;
已解释。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
Plan hash value: 1810242240
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 158 | 39404 (3)| 00:07:53 |
| 1 | SORT AGGREGATE | | 1 | 158 | | |
|* 2 | HASH JOIN | | 1247K| 187M| 39404 (3)| 00:07:53 |
| 3 | TABLE ACCESS FULL| TEST_SMALL | 4854 | 374K| 17 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL| TEST_BIG | 14M| 1106M| 39134 (2)| 00:07:50 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("TEST_BIG"."OBJECT_ID"="TEST_SMALL"."OBJECT_ID")
Note
-----
- dynamic sampling used for this statement
已选择20行。
SQL> set timing on
SQL> select count(test_big.object_name||test_small.object_name)
2 from test_big, test_small where test_big.object_id = test_small.object_id;
COUNT(TEST_BIG.OBJECT_NAME||TEST_SMALL.OBJECT_NAME)
---------------------------------------------------
1280000
已用时间: 00: 00: 21.42
1. 创建测试环境
大表test_big,小表test_small,二者通过test_big.object_id=test_small.object_id来关联。其中大表的object_id中会有重复记录,而小表中的object_id是唯一的,两个列上都有索引。
C:\Documents and Settings\yuechao.tianyc>sqlplus test/test
SQL*Plus: Release 10.2.0.1.0 - Production on 星期日 3月 29 22:37:13 2009
Copyright (c) 1982, 2005, Oracle. All rights reserved.
连接到:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> create table test_big as select * from dba_objects;
表已创建。
SQL> insert into test_big select * from test_big;
已创建50000行。
SQL> /
已创建100000行。
...
SQL> /
已创建6400000行。
SQL> commit;
提交完成。
SQL> create table test_small as select * from dba_objects where rownum < 5001;
表已创建。
SQL> create index ind_test_big on test_big(object_id);
索引已创建。
SQL> create index ind_test_small on test_small(object_id);
索引已创建。
2. 获取执行计划
分别使用大表和小表作为驱动行源,先看一下它们的执行计划:
-- 1. 使用test_big作为驱动行源
-- 执行步骤:(1)全表扫描test_big,得到行源A;(2)将A作为驱动行源,嵌套循环连接索引ind_test_small,得到行源B;(3)将行源B通过索引ind_test_small与表test_small关联,得到结果集。
SQL> explain plan for
2 select/*+ordered use_nl(test_big,test_small)*/ count(test_big.object_name||test_small.object_name)
3 from test_big, test_small where test_big.object_id = test_small.object_id;
已解释。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
Plan hash value: 3591390207
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 158 | 15M (1)| 53:19:22 |
| 1 | SORT AGGREGATE | | 1 | 158 | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEST_SMALL | 1 | 79 | 2 (0)| 00:00:01 |
| 3 | NESTED LOOPS | | 1247K| 187M| 15M (1)| 53:19:22 |
| 4 | TABLE ACCESS FULL | TEST_BIG | 14M| 1106M| 39134 (2)| 00:07:50 |
|* 5 | INDEX RANGE SCAN | IND_TEST_SMALL | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("test_big"."OBJECT_ID"="test_small"."OBJECT_ID")
Note
-----
- dynamic sampling used for this statement
已选择21行。
-- 2. 使用test_small作为驱动行源
-- 执行步骤:(1)全表扫描test_small,得到行源A;(2)将A作为驱动行源,嵌套循环连接索引ind_test_big,得到行源B;(3)将行源B通过索引ind_test_big与表test_big关联,得到结果集。
SQL> explain plan for
2 select/*+ordered use_nl(test_big,test_small)*/ count(test_big.object_name||test_small.object_name)
3 from test_small, test_big where test_big.object_id = test_small.object_id;
已解释。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
Plan hash value: 1952886871
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 158 | 1098K (1)| 03:39:42 |
| 1 | SORT AGGREGATE | | 1 | 158 | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEST_BIG | 257 | 20303 | 226 (0)| 00:00:03 |
| 3 | NESTED LOOPS | | 1247K| 187M| 1098K (1)| 03:39:42 |
| 4 | TABLE ACCESS FULL | TEST_SMALL | 4854 | 374K| 17 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | IND_TEST_BIG | 257 | | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("test_big"."OBJECT_ID"="test_small"."OBJECT_ID")
Note
-----
- dynamic sampling used for this statement
已选择21行。
3. 比较执行时间
比较上面两个不同的执行计划。看起来使用表test_small作为驱动行源更合理一些,它只有50001行,而表test_big有12800000行数据。而实际却不是这样,我们看一下他们各自的执行时间:
SQL> set timing on
-- 使用大表作为驱动行源
SQL> select/*+ordered use_nl(test_big,test_small)*/ count(test_big.object_name||test_small.object_name)
2 from test_big, test_small where test_big.object_id = test_small.object_id;
COUNT(TEST1.OBJECT_NAME||TEST2.OBJECT_NAME)
-------------------------------------------
12800000
已用时间: 00: 00: 36.70
-- 使用小表作为驱动行源
SQL> select/*+ordered use_nl(test1,test2)*/ count(test1.object_name||test2.object_name)
2 from test2, test1 where test1.object_id = test2.object_id;
COUNT(TEST1.OBJECT_NAME||TEST2.OBJECT_NAME)
-------------------------------------------
12800000
已用时间: 00: 02: 42.89
我们看到,使用大表作为驱动行源,耗时约36.7秒;而使用小表作为驱动行源,耗时达到2分42.89秒!
4. 原因
其实原因就在与大表的列object_id中有很多重复记录,当使用小表作为驱动行源时,全表扫描test_small的时间虽然很快,但对于test_small中的每一条记录,都对应test_big中的若干条记录,那么就需要根据查到的这些rowid,进行若干次的磁盘I/O来获得大表对应的数据。这里频繁的磁盘I/O就是问题的原因。因为test_big数据量很大,数据不可能存储在内存中。
而当使用大表作为驱动行源时,全表扫描test_big的时间虽然比较长,但每条记录都对应test_small中的一条记录,而且表test_small比较小,其数据及索引数据可以从内存中直接找到。这样耗费的时间就主要是全表扫描test_big的时间了,而这耗费不了太多的时间。在下面的测试中,只耗费了26.14秒:
SQL> select count(*) from test_big;
COUNT(*)
----------
12800000
已用时间: 00: 00: 26.14
SQL> set timing off
SQL> explain plan for
2 select count(*) from test_big;
已解释。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------
--------------------------------------------------------------------------
Plan hash value: 3224830981
-----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 38982 (2)| 00:07:48 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| TEST_BIG | 14M| 38982 (2)| 00:07:48 |
-----------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement
已选择13行。
5. 备注
这里只是一个小测试,来说明nested loop中,驱动行源的选择要根据实际情况而定,不是一成不变的。其实这个SQL使用hash join是最快的:
SQL> explain plan for
2 select count(test_big.object_name||test_small.object_name)
3 from test_big, test_small where test_big.object_id = test_small.object_id;
已解释。
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
Plan hash value: 1810242240
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 158 | 39404 (3)| 00:07:53 |
| 1 | SORT AGGREGATE | | 1 | 158 | | |
|* 2 | HASH JOIN | | 1247K| 187M| 39404 (3)| 00:07:53 |
| 3 | TABLE ACCESS FULL| TEST_SMALL | 4854 | 374K| 17 (0)| 00:00:01 |
| 4 | TABLE ACCESS FULL| TEST_BIG | 14M| 1106M| 39134 (2)| 00:07:50 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("TEST_BIG"."OBJECT_ID"="TEST_SMALL"."OBJECT_ID")
Note
-----
- dynamic sampling used for this statement
已选择20行。
SQL> set timing on
SQL> select count(test_big.object_name||test_small.object_name)
2 from test_big, test_small where test_big.object_id = test_small.object_id;
COUNT(TEST_BIG.OBJECT_NAME||TEST_SMALL.OBJECT_NAME)
---------------------------------------------------
1280000
已用时间: 00: 00: 21.42
发表评论
-
python学习摘要
2011-04-18 15:27 1373学习一门脚本语言是很 ... -
tmux快捷键
2011-04-16 07:39 1530摘要 http://rainbird.blog.51cto.c ... -
eclipse subclipse javahl 库加载错误
2011-04-13 17:31 2363网上搜集 http://islandlinux.org/how ... -
使用Msmtp mutt shell发邮件 (转)
2010-11-26 09:32 2804原文地址:http://fdsazi.blog.51cto.c ... -
Ubuntu10.0.4 Maven环境变量设置
2010-08-15 14:02 34471. 下载并解压缩apache-maven-2.2.1-bin ... -
Ubuntu10.0.4 Java环境变量设置
2010-08-15 14:00 4038Ubuntu10.0.4 下手工安装jdk及其环境变量设置 ... -
Managing Hierarchical Data in MySQL(转)
2010-07-09 10:01 1156http://dev.mysql.com/tech-resou ... -
JS的encode跟decode
2010-05-21 16:03 10601网上看到的,感觉能用得到,收藏下吧 /** * * URL ... -
Apache ActiveMQ
2009-12-25 15:46 3399一、特点 支持各种语言和协议的客户端。如:Java、C、C++ ... -
mysql数据的备份恢复命令
2009-12-14 15:37 1274记录下命令,害怕忘记! 导出整个数据库命令: D:\mys ... -
Struts2.18 的 interceptor
2009-12-08 08:20 3001首先定义我们自己的Interceptor package ... -
修改非安装版本mysql字符集
2009-12-08 08:08 1901如果我们的msyql是免安装版本,在windows系统下,my ... -
jqGrid学习 --------------自定义搜索
2009-12-06 15:45 15291定义自己的查询 <div id="myse ... -
jqGrid学习 -------------- 搜索工具栏
2009-12-06 15:13 13054搜索工具栏只是在列标题下面构造一个输入框。且使用表格的url进 ... -
jqGrid学习 -------------- 搜索
2009-12-06 13:32 9398表格中所有的列都可以作为搜索条件。 所用到的语言包文件 $ ... -
jqGrid学习 -------------- 自定义格式化类型
2009-12-06 13:04 8643<script> jQuery(" ... -
jqGrid学习 -------------- 格式化
2009-12-06 11:29 12447jqGrid的格式化是定义在 ... -
jqGrid学习 -------------- 自定义按钮
2009-12-06 11:14 16047用法: <script> ... jQue ... -
jqGrid学习 -------------- 翻页(2)
2009-12-06 10:32 8022jqGrid的翻页导航是一个方法,你可以事先定义一些其他操作, ... -
jqGrid学习 -------------- 翻页
2009-12-05 21:45 5341jqGrid的翻页要定义在html里,通常是在grid的下面, ...
相关推荐
complete flow of mapping loop nests onto CGRA. Experiment results on most kernels of the Polybench show that our proposed approach can improve the performance of the kernels by 42% on average, as ...
数据库中JOIN操作的实现主要有三种:嵌套循环连接(Nested Loop Join),归并连接(Merge Join)和散列连接或者哈稀连接(Hash Join)。其中嵌套循环连接又视情况又有两种变形:块嵌套循环连接和索引嵌套循环连接。
Sql中的三种物理连接操作 嵌套循环连接(Nested Loop Join) 合并连接(Merge Join) 哈希匹配(Hash Join)
基于Nested Logit模型的出行路线方式选择和时间价值计算,宗芳,祁文田,本文介绍了Nested Logit模型的效用最大化理论、选择树的建立以及其概率表达式;时间价值的基本计算公式。对人们由长春到吉林的出行路
索引嵌套循环联接(INLJ) 该项目是关于使用半流联接(INLJ)实现构建和分析数据仓库原型。 操作数据仓库 数据仓库的操作可以分为三个主要步骤: 创建数据仓库。 使用INLJ算法提取,转换和加载。...
这里是Spring的一个Nested事务的代码及数据库文件,因为NESTED资源很少,这里作出了一个通俗易懂的 让需要者下载。
Weblogic9异常解决nested errors.txtWeblogic9异常解决nested errors.txtWeblogic9异常解决nested errors.txtWeblogic9异常解决nested errors.txtWeblogic9异常解决nested errors.txt
Laravel开发-laravel-nested 向雄辩模型添加嵌套集验证
它应该在第一行以一个字符开始,在最后一行以num个字符结束。 示例:triLet1(3,A)应该返回A \ nAA \ nAAA。 当在主方法的打印语句中调用该方法时,将打印出类似的内容(但没有要点): 一种机管局AAA级程式2: ...
JSS插件,支持嵌套选择器 在规则中的选择器前放置& ,它将被父选择器替换并提取到。 用法示例 import jss from 'jss' import nested from 'jss-nested' jss . use ( nested ) const styleSheet = jss . ...
Laravel开发-eloquent-nested-attributes 嵌套属性允许您通过父级保存关联记录的属性。默认情况下,嵌套属性更新被关闭,您可以使用$nested属性启用它。启用嵌套属性时,将在模型上定义属性编写器。
java解决nested exception is java.lang.OutOfMemoryError Java heap space 解决OOM
java解决Handler processing failed; nested exception is java.lang.NoClassDefFoundError
Nested VM execution: new direction for KVM.
NULL 博文链接:https://ivan-yan.iteye.com/blog/1007671
We develop a new edge detection algorithm, holistically-nested edge detection (HED), which performs image-to-image prediction by means of a deep learning model that leverages fully convolutional ...
Gson对Java嵌套对象和JSON字符串之间的转换
Laravel开发-laravel-nestedset Laravel的嵌套集模型
nested fragments nested fragments nested fragments nested fragments