- 最后登录
- 2015-3-3
- 在线时间
- 3 小时
- 威望
- 24
- 金钱
- 209
- 注册时间
- 2012-6-21
- 阅读权限
- 10
- 帖子
- 11
- 精华
- 1
- 积分
- 24
- UID
- 523
|
1#
发表于 2012-6-25 16:16:11
|
查看: 8837 |
回复: 12
首先创建环境:
create table t (x number(10), y number(10));
insert into t values (1,110);
insert into t values (2,120);
insert into t values (2,80);
insert into t values (3,150);
insert into t values (3,30);
insert into t values (3,60);
commit;
查询表:
SQL> select * from t;
X Y
---------- ----------
1 110
2 120
2 80
3 150
3 30
3 60
执行如下语句:
SELECT x, SUM (y) AS total_y
FROM t
GROUP BY x
HAVING SUM (y) > (SELECT SUM (y)/3 FROM t)
ORDER BY total_y
/
在oracle11g之前的版本,会得到2行结果,11g的时候则no rows select
查看执行计划的不同:
oracle11g之前
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6 | 156 | 4 (50)| 00:00:01 |
| 1 | SORT ORDER BY | | 6 | 156 | 4 (50)| 00:00:01 |
|* 2 | FILTER | | | | | |
| 3 | HASH GROUP BY | | 6 | 156 | 4 (50)| 00:00:01 |
| 4 | TABLE ACCESS FULL| T | 6 | 156 | 2 (0)| 00:00:01 |
| 5 | SORT AGGREGATE | | 1 | 13 | | |
| 6 | TABLE ACCESS FULL| T | 6 | 78 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(SUM("Y")> (SELECT SUM("Y")/3 FROM "T" "T"))
11g:
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 6 | 234 | 4 (50)| 00:00:01 |
| 1 | SORT ORDER BY | | 6 | 234 | 4 (50)| 00:00:01 |
|* 2 | VIEW | VW_WIF_1 | 6 | 234 | 3 (34)| 00:00:01 |
| 3 | WINDOW BUFFER | | 6 | 156 | 3 (34)| 00:00:01 |
| 4 | HASH GROUP BY | | 6 | 156 | 3 (34)| 00:00:01 |
| 5 | TABLE ACCESS FULL| T | 6 | 156 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("ITEM_1">"ITEM_2"*3)
经验证,11g的时候如果把SELECT SUM (y)/3 FROM t修改成(SELECT SUM (y)/3 FROM t)/3,或者SELECT TO_NUMBER(SUM(y)/3) FROM t或者改成>=或者<等等情况都会使11g的执行计划也变成2次扫描表,做正确的filter,但是如果把/3写在里面就会导致执行计划使用WINDOW BUFFER,metalink上也没查到资料,请大神指导 |
|