关于oracle table()函数引起的全表扫描问题

oracle table()在某些场景下,为开发提供了便利之处。但如下sql的会造成全表扫描,导致系统负载变大

SQL> SELECT *
  2    FROM (select a.bill_code, sum(a.piece_num)
  3            from TB_WAYBILL a
  4           group by a.bill_code) c,
  5         TABLE(FN_STR_TO_TBL('200013011384,200013011409,1111', ',')) B
  6   WHERE c.BILL_CODE = B.CODE;

当出现oracle先分组统计在直接关联table()函数,会导致聚合函数所统计的列,所在表走不上索引。其它情况下关联table()出现全表扫描的情况暂未发现,如有后期将添加。欢迎指正探讨。


如下10053文件中给出的信息

----------------------------------------------trace文件开始(注这里篇幅有限,并没有给出全部)

Final query after transformations:******* UNPARSED QUERY IS *******
SELECT /*+ OPT_ESTIMATE (TABLE "KOKBF$" ROWS=3.000000 ) */ "C"."BILL_CODE" "BILL_CODE","C"."SUM(A.PIECE_NUM)" "SUM(A.PIECE_NUM)",SYS_OP_ATG(VALUE(KOKBF$),1,2,2) "ID",SYS_OP_ATG(VALUE(KOKBF$),2,3,2) "CODE" FROM  (SELECT "A"."BILL_CODE" "BILL_CODE",SUM("A"."PIECE_NUM") "SUM(A.PIECE_NUM)" FROM "ZDADMIN"."TB_WAYBILL" "A" GROUP BY "A"."BILL_CODE") "C",TABLE("ZDADMIN"."FN_STR_TO_TBL"('200013011384,200013011409,1111',',')) "KOKBF$" WHERE "C"."BILL_CODE"=SYS_OP_ATG(VALUE(KOKBF$),2,3,2)
kkoqbc: optimizing query block SEL$2 (#0)
        
        :
    call(in-use=5656, alloc=314384), compile(in-use=84240, alloc=87648), execution(in-use=12384, alloc=16200)


kkoqbc-subheap (create addr=0x2ab39e63de28)
****************
QUERY BLOCK TEXT
****************
select a.bill_code, sum(a.piece_num)
          from TB_WAYBILL a
         group by a.bill_code
---------------------
QUERY BLOCK SIGNATURE
---------------------
signature (optimizer): qb_name=SEL$2 nbfros=1 flg=0
  fro(0): flg=0 objn=80120 hint_alias="A"@"SEL$2"


-----------------------------
SYSTEM STATISTICS INFORMATION
-----------------------------
  Using NOWORKLOAD Stats
  CPUSPEEDNW: 2657 millions instructions/sec (default is 100)
  IOTFRSPEED: 4096 bytes per millisecond (default is 4096)
  IOSEEKTIM: 10 milliseconds (default is 10)
  MBRC: -1 blocks (default is 64)


***************************************
BASE STATISTICAL INFORMATION
***********************
Table Stats::
  Table: TB_WAYBILL  Alias:  A  (Using composite stats)
    #Rows: 1889543  #Blks:  61170  AvgRowLen:  217.00
Index Stats::
  Index: I_WAYBILL_1  Col#: 6
    LVLS: 2  #LB: 7009  #DK: 397  LB/K: 17.00  DB/K: 614.00  CLUF: 243976.00
  Index: PK_TB_WAYBILL  Col#: 1
    LVLS: 2  #LB: 8238  #DK: 1868565  LB/K: 1.00  DB/K: 1.00  CLUF: 1418270.00
Access path analysis for TB_WAYBILL
***************************************
SINGLE TABLE ACCESS PATH 
  Single Table Cardinality Estimation for TB_WAYBILL[A] 
  Table: TB_WAYBILL  Alias: A
    Card: Original: 1889543.000000  Rounded: 1889543  Computed: 1889543.00  Non Adjusted: 1889543.00
  Access Path: TableScan
    Cost:  11019.11  Resp: 11019.11  Degree: 0
      Cost_io: 10993.00  Cost_cpu: 832422515
      Resp_io: 10993.00  Resp_cpu: 832422515
  Best:: AccessPath: TableScan
         Cost: 11019.11  Degree: 1  Resp: 11019.11  Card: 1889543.00  Bytes: 0


Grouping column cardinality [ BILL_CODE]    1889543
***************************************


OPTIMIZER STATISTICS AND COMPUTATIONS
***************************************
GENERAL PLANS
***************************************
Considering cardinality-based initial join order.
Permutations for Starting Table :0
Join order[1]:  TB_WAYBILL[A]#0
GROUP BY sort
GROUP BY adjustment factor: 1.000000
GROUP BY cardinality:  1889543.000000, TABLE cardinality:  1889543.000000
    SORT ressource         Sort statistics
      Sort width:        6142 Area size:     1048576 Max Area size:  1073735680
      Degree:               1
      Blocks to Sort: 6709 Row size:     29 Total Rows:        1889543
      Initial runs:   2 Merge passes:  1 IO Cost / pass:       3636
      Total IO sort cost: 10345      Total CPU sort cost: 1972079915
      Total Temp space used: 53208000
***********************
Best so far:  Table#: 0  cost: 21425.9592  card: 1889543.0000  bytes: 32122231
***********************


****** Recost for ORDER BY (using index) ************
Access path analysis for TB_WAYBILL
***************************************
SINGLE TABLE ACCESS PATH 
  Single Table Cardinality Estimation for TB_WAYBILL[A] 
  Table: TB_WAYBILL  Alias: A
    Card: Original: 1889543.000000  Rounded: 1889543  Computed: 1889543.00  Non Adjusted: 1889543.00
  Access Path: TableScan
    Cost:  11019.11  Resp: 11019.11  Degree: 0
      Cost_io: 10993.00  Cost_cpu: 832422515
      Resp_io: 10993.00  Resp_cpu: 832422515
  Access Path: index (FullScan)
    Index: PK_TB_WAYBILL
    resc_io: 1426510.00  resc_cpu: 10924917024
    ix_sel: 1.000000  ix_sel_with_filters: 1.000000 
    Cost: 142685.26  Resp: 142685.26  Degree: 1
  Best:: AccessPath: IndexRange
  Index: PK_TB_WAYBILL
         Cost: 142685.26  Degree: 1  Resp: 142685.26  Card: 1889543.00  Bytes: 17


Join order[1]:  TB_WAYBILL[A]#0
Join order aborted: cost > best plan cost

--------------省略部分信息

注:上文里的cbo认为Card: Original: 1889543.000000  Rounded: 1889543  此处rounded输出行也是1889543(这个地方没有搞明白,实际输出只有两行)所以在关联前认为走全表扫描cost更少,下文里cbo将a表的分组后结果做为一个独立视图(下文中的$_subquery$_001  Alias:  C )去关联 table()函数


***************************************
BASE STATISTICAL INFORMATION
***********************
Table Stats::
  Table: KOKBF$  Alias: KOKBF$  (NOT ANALYZED)
    #Rows: 8168  #Blks:  100  AvgRowLen:  100.00
***********************
Table Stats::
  Table: from$_subquery$_001  Alias:  C  (NOT ANALYZED)
    #Rows: 0  #Blks:  0  AvgRowLen:  0.00
Access path analysis for from$_subquery$_001


Access path analysis for KOKBF$
***************************************
SINGLE TABLE ACCESS PATH 
  Single Table Cardinality Estimation for KOKBF$[KOKBF$] 
  Table: KOKBF$  Alias: KOKBF$
    Card: Original: 8168.000000    >> Single Tab Card adjusted from:8168.000000 to:3.000000
  Rounded: 3  Computed: 3.00  Non Adjusted: 8168.00
  Access Path: TableScan
    Cost:  20.06  Resp: 20.06  Degree: 0
      Cost_io: 20.00  Cost_cpu: 1774044
      Resp_io: 20.00  Resp_cpu: 1774044
  Best:: AccessPath: TableScan
         Cost: 20.06  Degree: 1  Resp: 20.06  Card: 3.00  Bytes: 0

----------------------------------------------trace文件结束(注这里篇幅有限,并没有给出全部)


如下演示实际强制表a使用使用索引以验证上面trace文件里的cost

SQL> set autotrace trace exp stat
SQL> set linesize 500
SQL> SELECT *
  2    FROM (select /*+index(a,PK_TB_WAYBILL)+*/ a.bill_code, sum(a.piece_num)
  3            from TB_WAYBILL a
  4           group by a.bill_code) c,
  5         TABLE(FN_STR_TO_TBL('200013011384,200013011409,1111', ',')) B
  6   WHERE c.BILL_CODE = B.CODE;




Execution Plan
----------------------------------------------------------
Plan hash value: 1808457990


------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                              | Name          | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |               |  8168 |   215K|   148K  (1)| 00:29:37 |       |       |
|   1 |  MERGE JOIN                            |               |  8168 |   215K|   148K  (1)| 00:29:37 |       |       |
|   2 |   SORT JOIN                            |               |  1986K|    47M|   147K  (1)| 00:29:36 |       |       |
|   3 |    VIEW                                |               |  1986K|    47M|   147K  (1)| 00:29:36 |       |       |
|   4 |     HASH GROUP BY                      |               |  1986K|    32M|   147K  (1)| 00:29:36 |       |       |
|   5 |      TABLE ACCESS BY GLOBAL INDEX ROWID| TB_WAYBILL    |  1986K|    32M|   147K  (1)| 00:29:36 | ROWID | ROWID |
|   6 |       INDEX FULL SCAN                  | PK_TB_WAYBILL |  1986K|       |   876   (1)| 00:00:11 |       |       |
|*  7 |   SORT JOIN                            |               |  8168 | 16336 |    21   (5)| 00:00:01 |       |       |
|   8 |    COLLECTION ITERATOR PICKLER FETCH   | FN_STR_TO_TBL |  8168 | 16336 |    20   (0)| 00:00:01 |       |       |
------------------------------------------------------------------------------------------------------------------------


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


   7 - access("C"."BILL_CODE"=SYS_OP_ATG(VALUE(KOKBF$),2,3,2))
       filter("C"."BILL_CODE"=SYS_OP_ATG(VALUE(KOKBF$),2,3,2))




Statistics
----------------------------------------------------------
         26  recursive calls
         72  db block gets
    1525827  consistent gets
       1705  physical reads
         72  redo size
        847  bytes sent via SQL*Net to client
        524  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          2  sorts (memory)
          0  sorts (disk)
          2  rows processed


SQL> 


-----------------------------------------------------------------------------------------本案例给出的优化建议如下

select distinct sid from v$mystat;

select b.*
  from V$session a, v$process b
 where a.sid = ??
   and a.paddr = b.addr; 

alter session set events '10053 trace name context forever , level 1';

SELECT *
  FROM (select a.bill_code, sum(a.piece_num)
          from TB_WAYBILL a
         group by a.bill_code) c
 WHERE exists
 (select 1
          from TABLE(FN_STR_TO_TBL('200013011384,200013011409,1111', ',')) B
         where c.bill_code = b.code);

alter session set events '10053 trace name context off';

将上面对应的trace文件找到,会发现cbo最终转换后的sql如下


----------------------------------------------trace文件开始(注这里篇幅有限,并没有给出全部)

Final query after transformations:******* UNPARSED QUERY IS *******
SELECT "A"."BILL_CODE" "BILL_CODE",SUM("A"."PIECE_NUM") "SUM(A.PIECE_NUM)" FROM TABLE("ZDADMIN"."FN_STR_TO_TBL"('200013011384,200013011409,1111',',')) "KOKBF$","ZDADMIN"."TB_WAYBILL" "A" WHERE "A"."BILL_CODE"=SYS_OP_ATG(VALUE(KOKBF$),2,3,2) GROUP BY "A"."BILL_CODE"

---

***************************************
BASE STATISTICAL INFORMATION
***********************
Table Stats::
  Table: TB_WAYBILL  Alias:  A  (Using composite stats)
    #Rows: 1889543  #Blks:  61170  AvgRowLen:  217.00
Index Stats::
  Index: I_WAYBILL_1  Col#: 6
    LVLS: 2  #LB: 7009  #DK: 397  LB/K: 17.00  DB/K: 614.00  CLUF: 243976.00
  Index: PK_TB_WAYBILL  Col#: 1
    LVLS: 2  #LB: 8238  #DK: 1868565  LB/K: 1.00  DB/K: 1.00  CLUF: 1418270.00
***********************
Table Stats::
  Table: KOKBF$  Alias: KOKBF$  (NOT ANALYZED)
    #Rows: 8168  #Blks:  100  AvgRowLen:  100.00
Access path analysis for KOKBF$
***************************************
SINGLE TABLE ACCESS PATH 
  Single Table Cardinality Estimation for KOKBF$[KOKBF$] 
  Table: KOKBF$  Alias: KOKBF$
    Card: Original: 8168.000000  Rounded: 8168  Computed: 8168.00  Non Adjusted: 8168.00
  Access Path: TableScan
    Cost:  20.06  Resp: 20.06  Degree: 0
      Cost_io: 20.00  Cost_cpu: 1937344
      Resp_io: 20.00  Resp_cpu: 1937344
  Best:: AccessPath: TableScan
         Cost: 20.06  Degree: 1  Resp: 20.06  Card: 8168.00  Bytes: 0


Access path analysis for TB_WAYBILL
***************************************
SINGLE TABLE ACCESS PATH 
  Single Table Cardinality Estimation for TB_WAYBILL[A] 
  Table: TB_WAYBILL  Alias: A
    Card: Original: 1889543.000000  Rounded: 1889543  Computed: 1889543.00  Non Adjusted: 1889543.00
  Access Path: TableScan
    Cost:  11019.11  Resp: 11019.11  Degree: 0
      Cost_io: 10993.00  Cost_cpu: 832422515
      Resp_io: 10993.00  Resp_cpu: 832422515
  Best:: AccessPath: TableScan
         Cost: 11019.11  Degree: 1  Resp: 11019.11  Card: 1889543.00  Bytes: 0


Grouping column cardinality [ BILL_CODE]    1889543

注:可能还有由于上面Card: Original: 1889543.000000  Rounded: 1889543   这个rounded输出记录数的问题,在关联前cbo依旧认定全表扫描的方式最优

Join order[1]:  TB_WAYBILL[A]#0  KOKBF$[KOKBF$]#1
Join order aborted: cost > best plan cost
***********************
Join order[2]:  KOKBF$[KOKBF$]#1  TB_WAYBILL[A]#0
    SORT ressource         Sort statistics
      Sort width:        6142 Area size:     1048576 Max Area size:  1073735680
      Degree:               1
      Blocks to Sort: 13 Row size:     13 Total Rows:           8168
      Initial runs:   1 Merge passes:  0 IO Cost / pass:          0
      Total IO sort cost: 0      Total CPU sort cost: 36666663
      Total Temp space used: 0


***************
Now joining: TB_WAYBILL[A]#0
***************
NL Join
  Outer table: Card: 255.25  Cost: 21.21  Resp: 21.21  Degree: 1  Bytes: 2
Access path analysis for TB_WAYBILL
  Inner table: TB_WAYBILL  Alias: A
  Access Path: TableScan
    NL Join:  Cost: 2809508.68  Resp: 2809508.68  Degree: 1
      Cost_io: 2802850.00  Cost_cpu: 212306345281
      Resp_io: 2802850.00  Resp_cpu: 212306345281
OPTIMIZER PERCENT INDEX CACHING = 85
  Access Path: index (UniqueScan)
    Index: PK_TB_WAYBILL
    resc_io: 1.00  resc_cpu: 8381
    ix_sel: 0.000001  ix_sel_with_filters: 0.000001 
    NL Join : Cost: 46.72  Resp: 46.72  Degree: 1
      Cost_io: 45.50  Cost_cpu: 38817733
      Resp_io: 45.50  Resp_cpu: 38817733
OPTIMIZER PERCENT INDEX CACHING = 85
  Access Path: index (AllEqUnique)
    Index: PK_TB_WAYBILL
    resc_io: 1.00  resc_cpu: 8381
    ix_sel: 0.000001  ix_sel_with_filters: 0.000001 
    NL Join : Cost: 46.72  Resp: 46.72  Degree: 1
      Cost_io: 45.50  Cost_cpu: 38817733
      Resp_io: 45.50  Resp_cpu: 38817733

注:在关联后,cbo在此处认定表a走索引的cost更少

  Best NL cost: 46.72
          resc: 46.72  resc_io: 45.50  resc_cpu: 38817733
          resp: 46.72  resp_io: 45.50  resc_cpu: 38817733
Join Card:  255.250000 = = outer (255.250000) * inner (1889543.000000) * sel (0.000001)
Join Card - Rounded: 255 Computed: 255.25
Grouping column cardinality [ BILL_CODE]    1
  Outer table:  KOKBF$  Alias: KOKBF$
    resc: 21.21  card 255.25  bytes: 2  deg: 1  resp: 21.21
  Inner table:  TB_WAYBILL  Alias: A
    resc: 11019.11  card: 1889543.00  bytes: 17  deg: 1  resp: 11019.11
    using dmeth: 2  #groups: 1
    SORT ressource         Sort statistics
      Sort width:        6142 Area size:     1048576 Max Area size:  1073735680
      Degree:               1
      Blocks to Sort: 1 Row size:     13 Total Rows:            255
      Initial runs:   1 Merge passes:  0 IO Cost / pass:          0
      Total IO sort cost: 0      Total CPU sort cost: 31975993
      Total Temp space used: 0
    SORT ressource         Sort statistics
      Sort width:        6142 Area size:     1048576 Max Area size:  1073735680
      Degree:               1
      Blocks to Sort: 6709 Row size:     29 Total Rows:        1889543
      Initial runs:   2 Merge passes:  1 IO Cost / pass:       3636
      Total IO sort cost: 10345      Total CPU sort cost: 1972079915
      Total Temp space used: 106406000
  SM join: Resc: 21448.17  Resp: 21448.17  [multiMatchCost=0.00]
SM Join
  SM cost: 21448.17 
     resc: 21448.17 resc_io: 21358.00 resc_cpu: 2875082430
     resp: 21448.17 resp_io: 21358.00 resp_cpu: 2875082430
  Outer table:  KOKBF$  Alias: KOKBF$
    resc: 21.21  card 255.25  bytes: 2  deg: 1  resp: 21.21
  Inner table:  TB_WAYBILL  Alias: A
    resc: 11019.11  card: 1889543.00  bytes: 17  deg: 1  resp: 11019.11
    using dmeth: 2  #groups: 1
    Cost per ptn: 6.43  #ptns: 1
    hash_area: 256 (max=262143) buildfrag: 1  probefrag: 6690  ppasses: 1
  Hash join: Resc: 11046.75  Resp: 11046.75  [multiMatchCost=0.00]
HA Join
  HA cost: 11046.75  
     resc: 11046.75 resc_io: 11013.00 resc_cpu: 1075961145
     resp: 11046.75 resp_io: 11013.00 resp_cpu: 1075961145
GROUP BY sort
GROUP BY adjustment factor: 1.000000
GROUP BY cardinality:  1.000000, TABLE cardinality:  255.000000
    SORT ressource         Sort statistics
      Sort width:        6142 Area size:     1048576 Max Area size:  1073735680
      Degree:               1
      Blocks to Sort: 1 Row size:     31 Total Rows:            255
      Initial runs:   1 Merge passes:  0 IO Cost / pass:          0
      Total IO sort cost: 0      Total CPU sort cost: 31975993
      Total Temp space used: 0
Plan cardinality mismatch: best card= 1.00000000000   curr card= 255.25000000000
Best:: JoinMethod: NestedLoop
       Cost: 47.72  Degree: 1  Resp: 47.72  Card: 255.25 Bytes: 19
***********************
Best so far:  Table#: 1  cost: 21.2108  card: 255.2500  bytes: 510
              Table#: 0  cost: 47.7203  card: 255.2500  bytes: 4845


----------------------------------------------trace文件结束(注这里篇幅有限,并没有给出全部)

被废止的第一种jion方式实际连接方式如下

SQL> SET AUTOTRACE TRACE EXP

SQL> SELECT *
  2    FROM (select /*+index(a,PK_TB_WAYBILL) leading(a)+*/ a.bill_code, sum(a.piece_num)
  3            from TB_WAYBILL a
  4           group by a.bill_code) c
  5   WHERE exists
  6   (select 1
  7            from TABLE(FN_STR_TO_TBL('200013011384,200013011409,1111', ',')) B
  8           where c.bill_code = b.code);


Execution Plan
----------------------------------------------------------
Plan hash value: 642200668


----------------------------------------------------------------------------------------------------------------------
| Id  | Operation                            | Name          | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |               |     1 |    19 |   148K  (1)| 00:29:37 |       |       |
|   1 |  SORT GROUP BY NOSORT                |               |     1 |    19 |   148K  (1)| 00:29:37 |       |       |
|   2 |   MERGE JOIN SEMI                    |               |     1 |    19 |   148K  (1)| 00:29:37 |       |       |
|   3 |    TABLE ACCESS BY GLOBAL INDEX ROWID| TB_WAYBILL    |  1986K|    32M|   147K  (1)| 00:29:36 | ROWID | ROWID |
|   4 |     INDEX FULL SCAN                  | PK_TB_WAYBILL |  1986K|       |   876   (1)| 00:00:11 |       |       |
|*  5 |    SORT UNIQUE                       |               |  8168 | 16336 |    21   (5)| 00:00:01 |       |       |
|   6 |     COLLECTION ITERATOR PICKLER FETCH| FN_STR_TO_TBL |  8168 | 16336 |    20   (0)| 00:00:01 |       |       |
----------------------------------------------------------------------------------------------------------------------


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


   5 - access("A"."BILL_CODE"=SYS_OP_ATG(VALUE(KOKBF$),2,3,2))
       filter("A"."BILL_CODE"=SYS_OP_ATG(VALUE(KOKBF$),2,3,2))


SQL> 





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值