帮ITPUB网友调SQL

http://www.itpub.net/viewthread.php?tid=1462612&extra=page%3D1&page=1 

SQL>  explain plan for   select ((v.yvalue * 300) / (u.xvalue * 50)), u.xtime
  2    from (select x.index_value xvalue, substr(x.update_time, 1, 14) xtime
  3            from tb_indexs x
  4           where x.id in (select  min(a.id)
  5                            from tb_indexs a
  6                           where a.code = 'HSI'
  7                             and a.update_time > 20110701000000
  8                             and a.update_time < 20110722000000
  9                           group by a.update_time)) u,
10         (select  y.index_value yvalue, substr(y.update_time, 1, 14) ytime
11            from tb_indexs y
12           where y.id in (select  min(b.id)
13                            from tb_indexs b
14                           where b.code = '000300'
15                             and b.update_time > 20110701000000
16                             and b.update_time < 20110722000000
17                           group by b.update_time)) v
18   where u.xtime = v.ytime
19   order by u.xtime;

Explained.

Elapsed: 00:00:01.85
SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------
--------------------
Plan hash value: 573554298

-----------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                 |     1 |    54 |    13   (8)| 00:00:01 |
|   1 |  SORT ORDER BY                    |                 |     1 |    54 |    13   (8)| 00:00:01 |
|   2 |   NESTED LOOPS                    |                 |     1 |    54 |    12   (0)| 00:00:01 |
|   3 |    MERGE JOIN CARTESIAN           |                 |     1 |    33 |    10   (0)| 00:00:01 |
|   4 |     NESTED LOOPS                  |                 |     1 |    27 |     6   (0)| 00:00:01 |
|   5 |      VIEW                         | VW_NSO_2        |     1 |     6 |     4   (0)| 00:00:01 |
|   6 |       HASH GROUP BY               |                 |     1 |    41 |     4   (0)| 00:00:01 |
|   7 |        TABLE ACCESS BY INDEX ROWID| TB_INDEXS       |     1 |    41 |     4   (0)| 00:00:01 |
|*  8 |         INDEX RANGE SCAN          | IDX_UPDATE_TIME |     1 |       |     3   (0)| 00:00:01 |
|   9 |      TABLE ACCESS BY INDEX ROWID  | TB_INDEXS       |     1 |    21 |     2   (0)| 00:00:01 |
|* 10 |       INDEX UNIQUE SCAN           | PK_INDEXS       |     1 |       |     1   (0)| 00:00:01 |
|  11 |     BUFFER SORT                   |                 |     1 |     6 |     8   (0)| 00:00:01 |
|  12 |      VIEW                         | VW_NSO_1        |     1 |     6 |     4   (0)| 00:00:01 |
|  13 |       HASH GROUP BY               |                 |     1 |    41 |     4   (0)| 00:00:01 |
|  14 |        TABLE ACCESS BY INDEX ROWID| TB_INDEXS       |     1 |    41 |     4   (0)| 00:00:01 |
|* 15 |         INDEX RANGE SCAN          | IDX_UPDATE_TIME |     1 |       |     3   (0)| 00:00:01 |
|* 16 |    TABLE ACCESS BY INDEX ROWID    | TB_INDEXS       |     1 |    21 |     2   (0)| 00:00:01 |
|* 17 |     INDEX UNIQUE SCAN             | PK_INDEXS       |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------

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

   8 - access("A"."UPDATE_TIME">20110701000000 AND "A"."CODE"='HSI' AND
              "A"."UPDATE_TIME"<20110722000000)
       filter("A"."CODE"='HSI')
  10 - access("X"."ID"="$nso_col_1")
  15 - access("B"."UPDATE_TIME">20110701000000 AND "B"."CODE"='000300' AND
              "B"."UPDATE_TIME"<20110722000000)
       filter("B"."CODE"='000300')
  16 - filter(SUBSTR(TO_CHAR("X"."UPDATE_TIME"),1,14)=SUBSTR(TO_CHAR("Y"."UPDATE_TIME"),1,14)
              )
  17 - access("Y"."ID"="$nso_col_1")

38 rows selected.

问题出在 

VIEW                         | VW_NSO_1        |
HASH GROUP BY               |                 |
  TABLE ACCESS BY INDEX ROWID| TB_INDEXS       |
   INDEX RANGE SCAN          | IDX_UPDATE_TIME |

以及

VIEW                         | VW_NSO_2        |
HASH GROUP BY               |                 |
  TABLE ACCESS BY INDEX ROWID| TB_INDEXS       |
   INDEX RANGE SCAN          | IDX_UPDATE_TIME |

CBO 认为只返回1行,但是实际上要返回2W行+ 

临时性的解决方法:

SQL> set autot trace
SQL> select /*+ cardinality(@a 20000) cardinality(@b 20000)  */ ((v.yvalue * 300) / (u.xvalue * 50)), u.xtime
  2    from (select x.index_value xvalue, substr(x.update_time, 1, 14) xtime
  3            from tb_indexs x
  4           where x.id in (select /*+ QB_NAME(a)*/ min(a.id)
  5                            from tb_indexs a
  6                           where a.code = 'HSI'
  7                             and a.update_time > 20110701000000
  8                             and a.update_time < 20110722000000
  9                           group by a.update_time)) u,
10         (select  y.index_value yvalue, substr(y.update_time, 1, 14) ytime
11            from tb_indexs y
12           where y.id in (select /*+ QB_NAME(b) */ min(b.id)
13                            from tb_indexs b
14                           where b.code = '000300'
15                             and b.update_time > 20110701000000
16                             and b.update_time < 20110722000000
17                           group by b.update_time)) v
18   where u.xtime = v.ytime
19   order by u.xtime;

3032 rows selected.

Elapsed: 00:00:15.07

Execution Plan
----------------------------------------------------------
Plan hash value: 2679503093

-----------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                 |   935 | 50490 |  1393   (7)| 00:00:17 |
|   1 |  SORT ORDER BY                    |                 |   935 | 50490 |  1393   (7)| 00:00:17 |
|*  2 |   HASH JOIN                       |                 |   935 | 50490 |  1392   (7)| 00:00:17 |
|   3 |    VIEW                           | VW_NSO_1        | 20000 |   117K|     4   (0)| 00:00:01 |
|   4 |     HASH GROUP BY                 |                 | 20000 |   800K|     4   (0)| 00:00:01 |
|   5 |      TABLE ACCESS BY INDEX ROWID  | TB_INDEXS       |     1 |    41 |     4   (0)| 00:00:01 |
|*  6 |       INDEX RANGE SCAN            | IDX_UPDATE_TIME |     1 |       |     3   (0)| 00:00:01 |
|*  7 |    HASH JOIN                      |                 | 31729 |  1487K|  1386   (7)| 00:00:17 |
|*  8 |     HASH JOIN                     |                 | 20000 |   527K|   695   (7)| 00:00:09 |
|   9 |      VIEW                         | VW_NSO_2        | 20000 |   117K|     4   (0)| 00:00:01 |
|  10 |       HASH GROUP BY               |                 | 20000 |   800K|     4   (0)| 00:00:01 |
|  11 |        TABLE ACCESS BY INDEX ROWID| TB_INDEXS       |     1 |    41 |     4   (0)| 00:00:01 |
|* 12 |         INDEX RANGE SCAN          | IDX_UPDATE_TIME |     1 |       |     3   (0)| 00:00:01 |
|  13 |      TABLE ACCESS FULL            | TB_INDEXS       |   678K|    13M|   678   (5)| 00:00:09 |
|  14 |     TABLE ACCESS FULL             | TB_INDEXS       |   678K|    13M|   678   (5)| 00:00:09 |
-----------------------------------------------------------------------------------------------------

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

   2 - access("Y"."ID"="$nso_col_1")
   6 - access("B"."UPDATE_TIME">20110701000000 AND "B"."CODE"='000300' AND
              "B"."UPDATE_TIME"<20110722000000)
       filter("B"."CODE"='000300')
   7 - access(SUBSTR(TO_CHAR("X"."UPDATE_TIME"),1,14)=SUBSTR(TO_CHAR("Y"."UPDATE_TIME"),1,14)
              )
   8 - access("X"."ID"="$nso_col_1")
  12 - access("A"."UPDATE_TIME">20110701000000 AND "A"."CODE"='HSI' AND
              "A"."UPDATE_TIME"<20110722000000)
       filter("A"."CODE"='HSI')


Statistics
----------------------------------------------------------
         29  recursive calls
          0  db block gets
       8351  consistent gets
       4977  physical reads
         72  redo size
     141975  bytes sent via SQL*Net to client
       2622  bytes received via SQL*Net from client
        204  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
       3032  rows processed

如果不采用HINT, SQL 估计 几个小时都不会有结果

posted on 2011-07-22 17:02  如果蜗牛有爱情  阅读(110)  评论(0编辑  收藏  举报

导航