问题说明: 

业务人员反馈系统跑批慢了,平时耗时5分钟,现在需要跑3个多小时,而且是每月10日和每月15日都会变慢。

环境说明:

DB:Oracle 11.2.0.4.0 RAC OS:AIX 7.1

问题分析:

抓取跑批对应的慢SQL,查看SQL文本如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

select  '2021/08/15',

         RelativeDeductaccno,

         RelativeDeductaccno,

         LB.Deductaccno,

         lb.putoutno,

         LB.Customerid,

         LB.Customername,

         SI.ManageOrgID,

         0,

         LB.Normalbalance + LB.Overduebalance + LB.Waitoverduebalance AS balance,

         LB.Normalbalance + LB.Overduebalance + LB.Waitoverduebalance AS Actualbalance,

         SaveBeginSum * 10000,

         LoanBeginSum * 10000,

         SaveStandardSum * 10000,

         LoanStandardSum * 10000,

         nvl(ImpawnRatio1, 0),

         nvl(ImpawnRatio2, 0),

         nvl(ImpawnRatio3, 0),

         nvl(ImpawnRatio4, 0),

         IncomeBase * 10000,

         LB.Executerate / (30 * 1000),

         LB.Loanrate / (30 * 1000),

         case

           when LB.Executerate < LB.Loanrate then

            LB.Executerate / (30 * 1000)

           else

            LB.Loanrate / (30 * 1000)

         end,

         SI.SaveRate / 1000,

         LB.maturitydate,

         IncomeReturnDay,

         0,

         '0',

         '1',

         MainSaveToLoanFlag,

         case

           when LB.LoanStatus <= '1' then

            1

           else

            0

         end as LoanStatus,

         lb.assetflag,

         lb.businesstype,

         nvl(case

               when cjc_fun_xxxxxxx(LB.putoutno, '2021/06/15') > 0 then

                cjc_fun_xxxxxxx(LB.putoutno, '2021/06/15')

               else

                0

             end,

             0),

         case

           when nvl(LB.assetflag, 0) = '1' and

                cjc_fun_xxxxxxx(LB.putoutno, '2021/06/15') > 0 then

            nvl(cjc_fun_xxxxxxx(LB.putoutno, '2021/06/15'), 0)

           else

            0

         end

    from cjcaaaaaaa_info SI, chen_balance LB

   where SI.putoutno = LB.putoutno

     and SI.Validdate <= '2021/08/15'

     and Status = '1'

     and ACCOUNTFLAG = '1'

手动执行,查看速度:

返回前100条记录很快,之后平均每10秒取出100行数据,最终取出全部结果集耗时很长。

查看执行计划:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

   PLAN_TABLE_OUTPUT

......

20 

21------------------------------------------------------------------------------------------------

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

23------------------------------------------------------------------------------------------------

24|   0 | SELECT STATEMENT             |                 |       |       | 14354 (100)|          |

25|   1 |  NESTED LOOPS                |                 |  6966 |  1367K| 14354   (1)| 00:00:01 |

26|   2 |   NESTED LOOPS               |                 |  6966 |  1367K| 14354   (1)| 00:00:01 |

27|*  3 |    TABLE ACCESS FULL         | cjcaaaaaaa_info |  6966 |   666K|   418   (1)| 00:00:01 |

28|*  4 |    INDEX UNIQUE SCAN         | chen_balance_PK |     1 |       |     1   (0)| 00:00:01 |

29|   5 |   TABLE ACCESS BY INDEX ROWID| chen_balance    |     1 |   103 |     2   (0)| 00:00:01 |

30------------------------------------------------------------------------------------------------

31 

32Predicate Information (identified by operation id):

33---------------------------------------------------

34 

35   3 - filter(("ACCOUNTFLAG"='1' AND "STATUS"='1' AND "SI"."VALIDDATE"<='2021/08/15'))

36   4 - access("SI"."PUTOUTNO"="LB"."PUTOUTNO")

37

查看执行计划,可以看到,即使cjcaaaaaaa_info走了全表扫描,cost也很低,预估的时间也很短。

难道是cjcaaaaaaa_info表统计信息不准确?

检查后发现表统计信息是准确的,cjcaaaaaaa_info数据量很小。

cjcaaaaaaa_info和chen_balance表关联关系很简单,where谓词条件也不复杂,那么是什么原因导致的SQL执行慢呢?

显然当前的cjcaaaaaaa_info和chen_balance关联采用NESTED LOOPS已经是最优的,尝试添加hint强制hash join速度更慢了。

既然表关联方式没问题,表访问路径没问题,还有可能哪块有问题呢?

仔细检查了SQL,发现查询的列有一处 可疑的地方:

1

2

3

4

5

6

7

8

9

10

11

12

13

......

nvl(case

               when cjc_fun_xxxxxxx(LB.putoutno, '2021/08/15') > 0 then

                cjc_fun_xxxxxxx(LB.putoutno, '2021/08/15')

               else

                0

             end,

             0),

         case

           when nvl(LB.assetflag, 0) = '1' and

                cjc_fun_xxxxxxx(LB.putoutno, '2021/08/15') > 0 then

            nvl(cjc_fun_xxxxxxx(LB.putoutno, '2021/08/15'), 0)

......

此处的cjc_fun_xxxxxxx看上去像是一个function,查看function的定义:

select dbms_metadata.get_ddl('FUNCTION','cjc_fun_xxxxxxx','CHENJ3') from dual;

函数部分由IF和ELSE两部分组成,每部分包含多个SELECT查询操作。

那么SQL执行慢,是否和cjc_fun_xxxxxxx函数有关呢?

注释掉原SQL中包含cjc_fun_xxxxxxx函数部分,再次执行SQL,速度恢复正常,不超过5分钟执行完成。

单独进行函数部分测试:

单独执行函数,速度很慢,每10秒返回100条记录

1

2

3

4

5

6

7

8

9

10

11

12

select case

         when nvl(LB.assetflag, 0) = 'https://www.fgba.net/' and

              cjc_fun_xxxxxxx(LB.putoutno, '2021/08/15') > 0 then

          nvl(cjc_fun_xxxxxxx(LB.putoutno, '2021/08/15'), 0)

         else

          0

       end

  from cjcaaaaaaa_info SI, chen_balance LB

 where SI.putoutno = LB.putoutno

   and SI.Validdate <= '2021/08/15'

   and Status = '1'

   and ACCOUNTFLAG = '1'

此时问题比较清晰了,就是因为cjc_fun_xxxxxxx函数部分导致SQL查询速度慢,那么为什么只有每月10号和每月15日速度慢呢?

主要是因为原SQL包含case when部分,当每月10号和每月15日时,cjc_fun_xxxxxxx函数部分执行的次数更多。

cjc_fun_xxxxxxx函数对性能究竟有多大的影响?

在满足sAssetFlag = '1'条件时,函数会执行8条select语句,并将结果集进行加和后返回。

在不满足sAssetFlag = '1'条件时,函数会执行14条select语句,并将结果集进行加和后返回。

并且除了执行的select次数不同外,执行的select语句也是不一样的,也就是在sAssetFlag值不同时,即使执行相同次数cjc_fun_xxxxxxx函数,执行时间也不同。

综合以上两点,SQL执行时间取决于函数执行次数,和单次函数执行的逻辑有关。

例如:

在最极端的情况下,查询的每条语句都会调用4次函数,每次函数执行14个select语句,在查询60000条数据时,后台实际会执行 336万条select语句。

解决方案:

和业务人员沟通,cjc_fun_xxxxxxx函数不能在优化了,但是可以使用中间表代替。 例如,跑批前提前单独执行cjc_fun_xxxxxxx函数部分,并将结果插入到临时表t1中, 在跑批时,不需要在执行cjc_fun_xxxxxxx函数,直接和临时表t1进行关联即可, 经测试,速度有明显改善,平均耗时不超过5分钟。

Oracle某行系统SQL优化相关推荐

  1. oracle权限advisor,Oracle自带工具sql优化集-SQL Tuning Advisor (使用心得体会)

    如何有效的诊断和监控高负载的SQL对于DBA来说并非是件容易的事情,对SQL语句手工调优需要很多的经验和技巧, 结合个人经验常见如下问题: . 对SQL语句本身进行优化以便获得更优的执行计划; . 合 ...

  2. 创建索引oracle 很慢,Oracle 建立索引及SQL优化

    复合索引用户可以在多个列上建立索引,这种索引叫做复合索引(组合索引).复合索引的创建方法与创建单一索引的方法完全一样.但复合索引在数据库操作期间所需的开销更小,可以代替多个单一索引. 如何某表的某个字 ...

  3. oracle hcmc,oracle11g中SQL优化(SQL TUNING)新特性之Adaptive Cursor Sharing (ACS)

    1.   ACS简介 Oracle Database 11g提供了Adaptive Cursor Sharing (ACS)功能,以克服以往不该共享的游标被共享的可能性.ACS使用两个新指标:sens ...

  4. oracle 命令行执行sql文件

    oracle 数据库执行sql文件 sqlplus 用户名/密码@数据库名 start 1.sql

  5. mysql和oracle 命令行执行sql文件 数据库执行sql文件 执行sql语句

    windows和linux操作相同 借鉴:http://www.361way.com/mysql-exec-sql-file/2646.html 方法一:mysql 调用法 操作方式如下: mysql ...

  6. oracle 检索行号,sql使用row_number()查询标记行号

    背景: 在分页功能中,记录需分页显示,需要row_number()函数标记行号. 数据表: 排序之前数据表显示: sql语句: 1 select ROW_NUMBER() over(order by ...

  7. 基于oracle 11g 的SQL优化

    1.查看当前数据库版本: select* from v$version;(以下示例基于oracle 11.2.0.1.0) 2.ROWID oracle数据库的表中的每一行数据都有一个唯一的标识符,该 ...

  8. 关于SQL优化的几点说明

    1. ORACLE DBA是如何进行SQL优化的 作为一个Oracle数据库管理员(DBA),SQL优化是他们的日常工作之一,主要目标是优化查询性能,减少查询时间,并提高数据库的整体性能. 以下是Or ...

  9. 高级SQL优化(二) ——《12年资深DBA教你Oracle开发与优化——性能优化部分》

    目录: Oracle数据完整性和锁机制  索引及优化之表分析  表分析.约束及表间关系  Oracle体系结构1 Oracle体系结构2  海量数据库及分区1  海量数据库及分区2  海量数据库及分区 ...

最新文章

  1. 块存储,文件存储和对象存储
  2. STL常用的拷贝和替换算法
  3. SSH+Oracle10G抛Disabling contextual LOB creation as createClob() m
  4. 横屏模式(landscape)下的UIDatePicker
  5. 雪花算法生成一个id
  6. JavaSE--异常信息打印
  7. sublime 添加 ConvertToUTF-8
  8. 图像缩放之双三次插值法
  9. python爬虫获取下一页_Python爬虫怎么获取下一页的URL和网页内容?
  10. 输入一个字符串,内有数字和非数字字符,例如: A123x456 17960? 302tab5876 将其中连续的数字作为一个整数,依次存放到一数组a中。例如,123存放在a[0],456放在a[1]中
  11. 《德米安》从那以后伤口很痛,但偶尔我会找到钥匙,沉入心底
  12. matlab使用pcode加密
  13. CUDA入门技术路线及基础知识
  14. 人体属性检测与深度实战
  15. 华为抱歉进程com.android.phone,搬运:华为手机adb工具,可以卸载华为全家桶
  16. 智能书包方案——智能书包重力测量模块CSM92F32
  17. 计算机毕业设计ssm电脑销售管理系统
  18. 数据ETL岗位实习面经
  19. 【机器学习】欠拟合 过拟合 正则化
  20. 有多少人用过连连支付啊?

热门文章

  1. python easy install_Python 安装easy_install详解
  2. mysql left join两个表,mysql left join 多个表
  3. java throw异常_java throw拋出异常详解
  4. ajax点评wnv冠军,对话wNv高层探知焦点 剑指世界冠军铸就王者路
  5. mysql与dns_借助mysql和DNS view实现智能DNS(centos6.3 x64环境)
  6. git 合并多次commit
  7. python-分页代码
  8. 紫书搜索 例题7-10 UVA - 11212 Editing a Book 迭代加深搜索 IDA*
  9. qt5.6.3版本移植arm
  10. KERNELRELEASE