SORT UNIQUE|AGGREGATE|GROUP BY|ORDER BY|JOIN
相信做oracle开发和管理的朋友对sort肯定不会陌生,大家通常都遇到这样那样的排序性能问题,所以我写这一系列关于sort的文章告诉大家在oracle里面sort是怎么一回事以及如果调整sort获得更好的性能。
首先,我们来回顾一下什么情况下需要sort,当取distinct值的时候需要,当进行merge join的时候也需要,当语句包含group by,order by的时候需要,当创建索引的时候需要等等。那么我们来看一下在oracle里面排序分为哪几种方式呢?
一.SORT UNIQUE : 发生在我们需要取distinct值的时候 , 也会发生在in的子查询里
sort unique发生在我们需要取distinct值的时候
SQL> set autotrace trace exp;
SQL> select distinct owner from test;
Execution Plan
———————————————————-
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=477 Card=15 Bytes=75
)
1 0 SORT (UNIQUE) (Cost=477 Card=15 Bytes=75)
2 1 TABLE ACCESS (FULL) OF ‘TEST’ (Cost=257 Card=193488 Byte
s=967440)
Statistics
———————————————————-
0 recursive calls
0 db block gets
2649 consistent gets
0 physical reads
0 redo size
564 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
15 rows processed
也会发生在in的子查询里
SQL> select owner from test where object_id in(select object_id from test1 where rownum<10);
Execution Plan
———————————————————-
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=530 Card=145116 Byte
s=3047436)
1 0 HASH JOIN (Cost=530 Card=145116 Bytes=3047436)
2 1 VIEW OF ‘VW_NSO_1′ (Cost=256 Card=9 Bytes=117)
3 2 SORT (UNIQUE)
4 3 COUNT (STOPKEY)
5 4 TABLE ACCESS (FULL) OF ‘TEST1′ (Cost=256 Card=1934
88 Bytes=580464)
6 1 TABLE ACCESS (FULL) OF ‘TEST’ (Cost=257 Card=193488 Byte
s=1547904)
为什么in子查询需要排序呢,因为oracle会把基于in的子查询
“select owner from test where object_id in(select object_id from test1)”
转换为类似
“select a.owner from test a,(select distinct object_id from test1) b where a.object_id=b.object_id”
如果in子查询里面选出的值可以通过主键或unique索引搜索得到,那么将不会进行sort unique的操作。
但自从10g R2开始,sort unique有了一些变化,sort unique变成了hash unique,采用新的hash算法代替了传统的sort unique,据oracle称在某些情况下排序性能是原来的5倍。
注意,sort的统计值将为0
SQL> select distinct owner from test;
Statistics
———————————————————-
0 recursive calls
0 db block gets
692 consistent gets
0 physical reads
0 redo size
781 bytes sent via SQL*Net to client
396 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
19 rows processed
SQL> select distinct owner from test;
Execution Plan
———————————————————-
Plan hash value: 2203132549
—————————————————————————
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
—————————————————————————
| 0 | SELECT STATEMENT | | 19 | 95 | 164 (5)| 00:00:02 |
| 1 | HASH UNIQUE | | 19 | 95 | 164 (5)| 00:00:02 |
| 2 | TABLE ACCESS FULL| TEST | 49909 | 243K| 158 (2)| 00:00:02 |
————————————————————————–
SQL> select owner from test where object_id in(select object_id from test1 where rownum<10);
Execution Plan
———————————————————-
Plan hash value: 2420636264
——————————————————————————–
——————
| Id | Operation | Name | Rows | Bytes | Cost
(%CPU)| Time |
——————————————————————————–
——————
| 0 | SELECT STATEMENT | | 5989 | 116K| 284
(2)| 00:00:04 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 665 | 4655 | 14
(0)| 00:00:01 |
| 2 | NESTED LOOPS | | 5989 | 116K| 284
(2)| 00:00:04 |
| 3 | VIEW | VW_NSO_1 | 9 | 117 | 156
(2)| 00:00:02 |
| 4 | HASH UNIQUE | | 9 | 18 |
| |
|* 5 | COUNT STOPKEY | | | |
| |
| 6 | TABLE ACCESS FULL | TEST1 | 49909 | 99818 | 156
(2)| 00:00:02 |
|* 7 | INDEX RANGE SCAN | IND_TEST_OBJECT_ID | 665 | | 2
(0)| 00:00:01 |
二.SORT AGGREGATE
sort aggregate通常发生在使用一些聚合函数的时候,sum(),avg(),min(),max(),count()等等,实际上sort aggregate不做真正的sort,并不会用到排序空间,而是通过一个全局变量+全表或全索引扫描来实现。伪代码如下
max_so_far = -INFINITE;
while (row* r=get_a_row_from_table(test_for_max)) {
if (r->n > max_so_far) max_so_far=n;
}
return max_so_far
SQL> select count(*) from test;
Execution Plan
———————————————————-
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=257 Card=1)
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF ‘TEST’ (Cost=257 Card=193488)
SQL> select sum(object_id) from test;
Execution Plan
———————————————————-
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=257 Card=1 Bytes=3)
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF ‘TEST’ (Cost=257 Card=193488 Byte
s=580464)
SQL> select min(object_id) from test;
Execution Plan
———————————————————-
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=257 Card=1 Bytes=3)
1 0 SORT (AGGREGATE)
2 1 INDEX (FULL SCAN (MIN/MAX)) OF ‘IND_TEST_OBJECT_ID’ (NON
-UNIQUE) (Cost=257 Card=193488 Bytes=580464)
SQL> select max(object_id) from test;
Execution Plan
———————————————————-
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=257 Card=1 Bytes=3)
1 0 SORT (AGGREGATE)
2 1 INDEX (FULL SCAN (MIN/MAX)) OF ‘IND_TEST_OBJECT_ID’ (NON
-UNIQUE) (Cost=257 Card=193488 Bytes=580464)
SQL> select avg(object_id) from test;
Execution Plan
———————————————————-
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=257 Card=1 Bytes=3)
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF ‘TEST’ (Cost=257 Card=193488 Byte
s=580464)
SQL> select count(*) from test;
Statistics
———————————————————-
0 recursive calls
0 db block gets
2649 consistent gets
0 physical reads
0 redo size
381 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
三.SORT GROUP BY
SORT GROUP BY会发生在有group by子句的时候
SQL> select owner from test group by owner;
15 rows selected.
Execution Plan
———————————————————-
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=477 Card=15 Bytes=75
)
1 0 SORT (GROUP BY) (Cost=477 Card=15 Bytes=75)
2 1 TABLE ACCESS (FULL) OF ‘TEST’ (Cost=257 Card=193488 Byte
s=967440)
Statistics
———————————————————-
0 recursive calls
0 db block gets
2649 consistent gets
0 physical reads
0 redo size
564 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
15 rows processed
在10g R2里又有了变化,sort group by被hash group by所代替
SQL> select owner from test group by owner;
19 rows selected.
Execution Plan
———————————————————-
Plan hash value: 1435881708
—————————————————————————
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
—————————————————————————
| 0 | SELECT STATEMENT | | 19 | 95 | 164 (5)| 00:00:02 |
| 1 | HASH GROUP BY | | 19 | 95 | 164 (5)| 00:00:02 |
| 2 | TABLE ACCESS FULL| TEST | 49909 | 243K| 158 (2)| 00:00:02 |
—————————————————————————
Statistics
———————————————————-
1 recursive calls
0 db block gets
692 consistent gets
0 physical reads
0 redo size
781 bytes sent via SQL*Net to client
396 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
19 rows processed
联想到上面提到的sort unique也是被hash unique所代替,我们可以肯定10g R2用了更多基于hash算法的东西,我们也期待在数据库其他方面10g R2也带给我们更多的好处。
四.SORT ORDER BY
SORT ORDER BY会发生在有order by子句的时候
SQL> select owner from test order by owner;
193488 rows selected.
Execution Plan
———————————————————-
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=666 Card=193488 Byte
s=967440)
1 0 SORT (ORDER BY) (Cost=666 Card=193488 Bytes=967440)
2 1 TABLE ACCESS (FULL) OF ‘TEST’ (Cost=257 Card=193488 Byte
s=967440)
Statistics
———————————————————-
0 recursive calls
0 db block gets
2649 consistent gets
0 physical reads
0 redo size
2528735 bytes sent via SQL*Net to client
142392 bytes received via SQL*Net from client
12901 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
193488 rows processed
五.SORT JOIN
SORT JOIN发生在出现merge join的情况下,两张关联的表要各自做sort,然后再merge
SQL> select /*+ use_merge(a b)*/ a.owner from test a,test1 b where a.object_id=b.object_id and rownum<10;
9 rows selected.
Execution Plan
———————————————————-
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1354 Card=9 Bytes=99
)
1 0 COUNT (STOPKEY)
2 1 MERGE JOIN (Cost=1354 Card=3119800512 Bytes=34317805632)
3 2 SORT (JOIN) (Cost=737 Card=193488 Bytes=1547904)
4 3 TABLE ACCESS (FULL) OF ‘TEST’ (Cost=257 Card=193488
Bytes=1547904)
5 2 SORT (JOIN) (Cost=617 Card=193488 Bytes=580464)
6 5 TABLE ACCESS (FULL) OF ‘TEST1′ (Cost=256 Card=193488
Bytes=580464)
Statistics
———————————————————-
0 recursive calls
0 db block gets
5251 consistent gets
0 physical reads
0 redo size
444 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
转载:http://blog.163.com/cyh_1987/blog/static/39469292012922103927464/
SORT UNIQUE|AGGREGATE|GROUP BY|ORDER BY|JOIN的更多相关文章
- mongodb的聚合aggregate|group|match|project|sort|limit|skip|unwind
聚合 aggregate 聚合(aggregate)主要用于计算数据,类似sql中的sum().avg() 语法 db.集合名称.aggregate([{管道:{表达式}}]) 管道 管道在Unix和 ...
- 学习mongo系列(七)aggregate() ,$group() 管道
aggregate()聚合,主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果.有点类似sql语句中的 count(*) 接上边的数据库: > db.user.aggregate ...
- MySql学习(二) —— where / having / group by / order by / limit 简单查询
注:该MySql系列博客仅为个人学习笔记. 这篇博客主要记录sql的五种子句查询语法! 一个重要的概念:将字段当做变量看,无论是条件,还是函数,或者查出来的字段. select五种子句 where 条 ...
- Hash unique和Sort unique
SQL> set linesize 200 SQL> set pagesize 200 SQL> set autot trace SQL> select distinct de ...
- 【MySQL】sort by then group by
tb: ### 需求:根据id进行分组,找到分组内hour中最大的一项 错误写法: select id, max(hour) from tb group by id; 正确的写法: ### 需求:根据 ...
- Aggregate (GROUP BY) Function Descriptions
w Table 13.25 Aggregate (GROUP BY) Functions Name Description AVG() Return the average value of the ...
- 一次 group by + order by 性能优化分析
一次 group by + order by 性能优化分析 最近通过一个日志表做排行的时候发现特别卡,最后问题得到了解决,梳理一些索引和MySQL执行过程的经验,但是最后还是有5个谜题没解开,希望大家 ...
- ORA-24408: could not generate unique server group name
一台新虚拟机,CentOS 6.5系统,用lnmp一键安装包安装好Nginx + PHP环境,再安装Oracle客户端,准备搭建PHP连接Oracle,访问oracle.php,测试连接Oracle的 ...
- where / having / group by / order by / limit 简单查询
目录 1.基础查询 -- where 2. group by 与 统计函数 3. having 4.where + group by + having + 函数 综合查询 5. order by + ...
随机推荐
- windows xp 无法连接wpa无线网络
其实以前一直是可以的,不知为什么前几天忽然就不能加入原有的无线网了.我的无线网是WPA加密的,采用DHCP分配IP(但针对特定MAC地址分配静态IP). 在网上找了许久,有的网友认为应该把无线网卡(那 ...
- linux中U盘umonut时出现“Device is busy”的解决方法
问题: #umount /dev/sda1 umount: /mnt/usb: device is busy 查找占用目录进程: #lsof |grep /mnt/usb bash 1971 root ...
- 关于LINUX权限-bash: ./startup.sh: Permission denied
关于LINUX权限-bash: ./startup.sh: Permission denied <script type="text/javascript"></ ...
- 获取CentOS系统详情的九个uname命令实例
当你在控制台模式下,无法通过“鼠标右键 > 关于”获取操作系统的信息.这时,在Linux下,你可以使用uname命令,帮助你完成这些工作. Uname是unix name的缩写.在控制台中实际使 ...
- sql查询字段值的换行及回车符
SQL的换行.回车符,在MySQL.SQL Server和Oracle中均有不同,下面以列表显示. MySQL SQL Server Oracle 换行符 \n或\r\n或CHAR(10) CHA ...
- .NET中使用OleDb读取Excel
在.NET中可以用OleDb(Object linking and embeding DataBase)来访问Excel using System; using System.Data; using ...
- 总结JavaScript(Iframe、window.open、window.showModalDialog)父窗口与子窗口之间的操作
一.Iframe 篇 //&&&&&&&&&&&&&&&&&&a ...
- arcgis javascript dojo
一.为什么说ArcGIS API for JavaScript是构建于Dojo之上的? 1. 编写ArcGIS API for JavaScript的ESRI开发者使用Dojo来简化他们的开发过程,同 ...
- python 内建函数 type() 和 isinstance() 介绍
Python 不支持方法或函数重载, 因此你必须自己保证调用的就是你想要的函数或对象.一个名字里究竟保存的是什么?相当多,尤其是这是一个类型的名字时.确认接收到的类型对象的身份有很多时候都是很有用的. ...
- Android构建boot.img(二):kernel的拷贝与打包
上文已经对boot.img其中组成部分之一ramdisk.img做了分析,boot.img另外一个重要的组成部分就是kernel了, 这里所说的kernel,可以只理解为位于out/target/pr ...