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 估计 几个小时都不会有结果