帮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 估计 几个小时都不会有结果
浙公网安备 33010602011771号