字段类型不一致导致的全表扫描

销售订单优化报告

监控后台语句

UPDATE T_SD_SaleOrderEntry

   SET (FOrderedQty, FUnOrderedQty) =

       (SELECT (ROUND(CAST((poe.FBaseQty / NVL(FBaseConvsRate,1)) AS

                           NUMBER(28,16)),

                     mu.FQtyPrecision) + T_SD_SaleOrderEntry.FOrderedQty) FORDEREDQTY,

              (T_SD_SaleOrderEntry.FQty -

               (ROUND(CAST((poe.FBaseQty /NVL(FBaseConvsRate,1)) AS

                            NUMBER(28,16)),

                      mu.FQtyPrecision) + T_SD_SaleOrderEntry.FOrderedQty)) FUNORDEREDQTY

          FROM T_SM_PurOrderEntry POE

          LEFTOUTERJOIN T_BD_MultiMeasureUnit MU

            ON poe.FMaterialID = mu.FMaterialID

         WHERE (poe.FSourceBillEntryID =T_SD_SaleOrderEntry.FIDAND

               (((poe.FParentID IN ('LlBN+WXBSsiRN5zSo9wMfjFxv60='))AND

              T_SD_SaleOrderEntry.FMaterialID = poe.FMaterialID)AND

              T_SD_SaleOrderEntry.FUnitID = mu.FMeasureUnitID)))

 WHERE T_SD_SaleOrderEntry.FIDIN

       (SELECT T_SD_SaleOrderEntry.FID

          FROM T_SD_SaleOrderEntry,T_SM_PurOrderEntry POE

          LEFTOUTERJOIN T_BD_MultiMeasureUnit MU

            ON poe.FMaterialID = mu.FMaterialID

         WHERE (poe.FSourceBillEntryID =T_SD_SaleOrderEntry.FIDAND

               (((poe.FParentID IN ('LlBN+WXBSsiRN5zSo9wMfjFxv60='))AND

              T_SD_SaleOrderEntry.FMaterialID = poe.FMaterialID)AND

              T_SD_SaleOrderEntry.FUnitID = mu.FMeasureUnitID)))

   ANDEXISTS

 (SELECT (ROUND(CAST((poe.FBaseQty / NVL(FBaseConvsRate,1)) AS

                           NUMBER(28,16)),

                     mu.FQtyPrecision) + T_SD_SaleOrderEntry.FOrderedQty) FORDEREDQTY,

              (T_SD_SaleOrderEntry.FQty -

               (ROUND(CAST((poe.FBaseQty /NVL(FBaseConvsRate,1)) AS

                            NUMBER(28,16)),

                      mu.FQtyPrecision) + T_SD_SaleOrderEntry.FOrderedQty)) FUNORDEREDQTY

          FROM T_SM_PurOrderEntry POE

          LEFTOUTERJOIN T_BD_MultiMeasureUnit MU

            ON poe.FMaterialID = mu.FMaterialID

         WHERE (poe.FSourceBillEntryID =T_SD_SaleOrderEntry.FIDAND

               (((poe.FParentID IN ('LlBN+WXBSsiRN5zSo9wMfjFxv60='))AND

              T_SD_SaleOrderEntry.FMaterialID = poe.FMaterialID)AND

              T_SD_SaleOrderEntry.FUnitID = mu.FMeasureUnitID)))

发现IO比较高,接近5G byte。查看语句,语句本身没有问题,不应该需要这么高的IO量,进行了语句的计划分析。 

ExecutionPlan

----------------------------------------------------------

Planhash value: 4157953725

 

--------------------------------------------------------------------------------------------------------

|Id  | Operation                     | Name                   | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT              |                        |     1 |  231 |   171K  (1)| 00:34:23 |

|   1 | NESTED LOOPS                |                        |     1 |  231 |   171K  (1)| 00:34:23 |

|*  2 |  HASH JOIN                   |                        |     1 |  173 |   171K  (1)| 00:34:23 |

|   3 |   TABLE ACCESS BY INDEX ROWID| T_SM_PURORDERENTRY     |    8 |   688 |     6  (0)| 00:00:01 |

|*  4 |    INDEX RANGE SCAN          |IX_SM_POEPARENT        |     8 |      |     2   (0)| 00:00:01 |

|   5 |   TABLE ACCESS FULL          |T_SD_SALEORDERENTRY    |  8200K|  680M|   171K  (1)| 00:34:22 |

|*  6 |  INDEX RANGE SCAN            |IDX_MULTIMEASUREUNIT_1 |     1 |    58 |    1   (0)| 00:00:01 |

--------------------------------------------------------------------------------------------------------

 

PredicateInformation (identified by operation id):

---------------------------------------------------

 

   2 -access("POE"."FSOURCEBILLENTRYID"=SYS_OP_C2C("T_SD_SALEORDERENTRY"."FID") AND

             "T_SD_SALEORDERENTRY"."FMATERIALID"="POE"."FMATERIALID")

   4 -access("POE"."FPARENTID"='LlBN+WXBSsiRN5zSo9wMfjFxv60=')

   6 -access("POE"."FMATERIALID"="MU"."FMATERIALID"AND

             "T_SD_SALEORDERENTRY"."FUNITID"="MU"."FMEASUREUNITID")

 

 

Statistics

----------------------------------------------------------

          0 recursive calls

          0 db block gets

          4 consistent gets

          0 physical reads

          0 redo size

        331 bytes sent via SQL*Net to client

        513 bytes received via SQL*Net from client

          1 SQL*Net roundtrips to/from client

          0 sorts (memory)

          0 sorts (disk)

0        rows processed

发现了其中一条子查询全表扫描了T_SD_SALEORDERENTRY,820万行数据量,700M的IO量。分析语句,发现执行过程中传递谓词出现系统字段转换SYS_OP_C2C access("POE"."FSOURCEBILLENTRYID"=SYS_OP_C2C("T_SD_SALEORDERENTRY"."FID")

经过对两张表的表结构进行分析,是由于FSOURCEBILLENTRYID的数据类型与"T_SD_SALEORDERENTRY"."FID"的数据类型不一致导致的。所以进行的数据类型的重新定义。优化后的语句计划如下: 

ExecutionPlan

----------------------------------------------------------

Planhash value: 2866515873

 

--------------------------------------------------------------------------------------------------------

|Id  | Operation                     | Name                   | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT              |                        |     1 |  227 |    11   (0)| 00:00:01 |

|   1 | NESTED LOOPS                |                        |     1 |  227 |    11   (0)| 00:00:01 |

|   2 |  NESTED LOOPS                |                        |     8 | 1352 |    10   (0)| 00:00:01 |

|   3 |   TABLE ACCESS BY INDEX ROWID| T_SM_PURORDERENTRY     |    8 |   656 |     6  (0)| 00:00:01 |

|*  4 |    INDEX RANGE SCAN          |IX_SM_POEPARENT        |     8 |      |     2   (0)| 00:00:01 |

|*  5 |   TABLE ACCESS BY INDEX ROWID| T_SD_SALEORDERENTRY    |    1 |    87 |     1  (0)| 00:00:01 |

|*  6 |    INDEX UNIQUE SCAN         |PK_SALEORDERENTRY      |     1 |      |     1   (0)| 00:00:01 |

|*  7 |  INDEX RANGE SCAN            |IDX_MULTIMEASUREUNIT_1 |     1 |    58 |    1   (0)| 00:00:01 |

--------------------------------------------------------------------------------------------------------

 

PredicateInformation (identified by operation id):

---------------------------------------------------

 

   4 -access("POE"."FPARENTID"='LlBN+WXBSsiRN5zSo9wMfjFxv60=')

   5 - filter("T_SD_SALEORDERENTRY"."FMATERIALID"="POE"."FMATERIALID")

   6 -access("POE"."FSOURCEBILLENTRYID"="T_SD_SALEORDERENTRY"."FID")

   7 -access("POE"."FMATERIALID"="MU"."FMATERIALID"AND

             "T_SD_SALEORDERENTRY"."FUNITID"="MU"."FMEASUREUNITID")

 

 

Statistics

----------------------------------------------------------

          1 recursive calls

          0 db block gets

          4 consistent gets

          0 physical reads

          0 redo size

        331 bytes sent via SQL*Net to client

        513 bytes received via SQL*Net from client

          1 SQL*Net roundtrips to/from client

          0 sorts (memory)

          0 sorts (disk)

0        rows processed

新的执行计划只有87k的数据吞吐量。执行时间也由原来的30秒提升至0.01S。

这个为EAS数据库设计的问题。所有的表结构在存储外键的FFSOURCEBILLENTRYID的数据类型均为NVARCHAR类型,而存储主键的FID为VARCHAR。所以,在上下游单据联查,更新和删除的时候,会产生很大的效率问题。特别是供应链和财务模块相关大数据量的业务表。严重影响用户体验。需要逐一的进行表结构优化或者创建函数索引。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值