Oracle数据库数据恢复、性能优化

找回密码
注册
搜索
热搜: 活动 交友 discuz
发新帖

24

积分

0

好友

2

主题
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上也没查到资料,请大神指导
2#
发表于 2012-6-25 16:25:14

有两行的

Connected to Oracle Database 11g Enterprise Edition Release 11.1.0.6.0
Connected as sys@192.168.253.248:1521/orcl AS SYSDBA

SQL>
SQL> SELECT x, SUM (y) AS total_y
  2  FROM t
  3  GROUP BY x
  4  HAVING SUM (y) > (SELECT SUM (y)/3 FROM t)
  5  ORDER BY total_y;

          X    TOTAL_Y
----------- ----------
          2        200
          3        240

SQL>

回复 只看该作者 道具 举报

3#
发表于 2012-6-25 16:28:36
可以发下你的执行计划么,我这边测试多个11g的库都用了window buffer导致没有结果,一个朋友的11g库也是如此。

回复 只看该作者 道具 举报

4#
发表于 2012-6-25 16:29:24

11.2不行

SQL*Plus: Release 11.2.0.1.0 Production on Mon Jun 25 16:29:42 2012

Copyright (c) 1982, 2009, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> conn scott/tiger
Connected.
SELECT t1.x, SUM(t1.y) AS total_y
  FROM t t1
GROUP BY t1.x
HAVING SUM(t1.y) > (SELECT SUM(t2.y) / 3 FROM t t2)
  5  /

no rows selected

SQL>

回复 只看该作者 道具 举报

5#
发表于 2012-6-25 16:30:44
测试11g的版本为11.2.0.2以及11.2.0.3

回复 只看该作者 道具 举报

6#
发表于 2012-6-25 16:34:49
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID        aprr3bq7895ad, child number 0
-------------------------------------
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

Plan hash value: 1651950043

-----------------------------------------------------------------------------------------------------------------------
| Id  | Operation              | Name         | Starts | E-Rows | A-Rows |        A-Time         | Buffers |  OMem |  1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |        1 |           |          0 |00:00:00.01 |         3 |           |           |              |
|   1 |  SORT ORDER BY              |          |        1 |         6 |          0 |00:00:00.01 |         3 |  1024 |  1024 |              |
|*  2 |   VIEW                      | VW_WIF_1 |        1 |         6 |          0 |00:00:00.01 |         3 |           |           |              |
|   3 |    WINDOW BUFFER      |          |        1 |         6 |          3 |00:00:00.01 |         3 |  2048 |  2048 | 2048  (0)|
|   4 |     HASH GROUP BY     |          |        1 |         6 |          3 |00:00:00.01 |         3 |   948K|   948K|  714K (0)|
|   5 |      TABLE ACCESS FULL| T         |        1 |         6 |          6 |00:00:00.01 |         3 |           |           |              |
-----------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("ITEM_1">"ITEM_2"*3)

Note
-----
   - dynamic sampling used for this statement (level=2)


27 rows selected.

[ 本帖最后由 26856649 于 2012-6-25 16:37 编辑 ]

回复 只看该作者 道具 举报

7#
发表于 2012-6-25 16:37:42
发愁了,求大神解答~

回复 只看该作者 道具 举报

8#
发表于 2012-6-25 23:14:46
可以用 _remove_aggr_subquery 参数 还原 到 10g 中的表现


SQL>
SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE    11.2.0.3.0      Production
TNS for Linux: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production

SQL> set linesize 200 pagesize 2000
SQL> SELECT x, SUM (y) AS total_y
  2  FROM t
  3  GROUP BY x
  4  HAVING SUM (y) > (SELECT SUM (y)/3 FROM t)
  5  ORDER BY total_y
  6  /

no rows selected


Execution Plan
----------------------------------------------------------
Plan hash value: 1651950043

----------------------------------------------------------------------------------
| 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)

Note
-----
   - dynamic sampling used for this statement (level=2)










SQL>  alter session set "_remove_aggr_subquery"=false;

Session altered.

SQL> SELECT x, SUM (y) AS total_y
  2  FROM t
  3  GROUP BY x
  4  HAVING SUM (y) > (SELECT SUM (y)/3 FROM t)
  5  ORDER BY total_y
  6  /

         X    TOTAL_Y
---------- ----------
         2        200
         3        240


Execution Plan
----------------------------------------------------------
Plan hash value: 4167292448

-----------------------------------------------------------------------------
| 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"))

Note
-----
   - dynamic sampling used for this statement (level=2)

回复 只看该作者 道具 举报

9#
发表于 2012-6-25 23:16:50
_remove_aggr_subquery   enables removal of subsumed aggregated subquery

回复 只看该作者 道具 举报

10#
发表于 2012-6-25 23:23:15
Bug 9189996 - Wrong Results with uncorrelated subquery removal [ID 9189996.8]

回复 只看该作者 道具 举报

11#
发表于 2012-6-25 23:24:48
好奇,大神是如何知道使用_remove_aggr_subquery隐含参数的。

回复 只看该作者 道具 举报

12#
发表于 2012-6-25 23:28:53
无所不能的大神啊!!!

回复 只看该作者 道具 举报

13#
发表于 2012-6-26 17:30:46
好贴,学习了。

同问,大神是如何知道并使用这个参数的?

回复 只看该作者 道具 举报

您需要登录后才可以回帖 登录 | 注册

QQ|手机版|Archiver|Oracle数据库数据恢复、性能优化

GMT+8, 2024-11-15 19:59 , Processed in 0.056022 second(s), 22 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部
TEL/電話+86 13764045638
Email service@parnassusdata.com
QQ 47079569