ABAP程序效率优化系列之④——开发优化之数据库(ST05那些事儿)

ABAP程序效率优化系列文章历史

ABAP程序效率优化系列之①——业务层面的优化

ABAP程序效率优化系列之②——开发优化之ABAP时间

ABAP程序效率优化系列之③——开发优化之读取数据库


写在前面


1、读取数据库优化的这两篇(上一篇和这一篇),对于HANA来说意义不大,一直在HANA数据库上进行开发的朋友请忽略

2、本文中的所有例子都是ORACLE数据库上的

3、大家在测试时,如果遇到与我不同的测试结果,也属于正常现象

4、我的目的是让大家通过ST05看到SQL的执行轨迹,了解它大概是怎么回事。然后通过HINTS的方式,在执行轨迹不符合我们的预期时,进行适当的干预

5、性能优化在运维项目上的作用尤其大,建设项目的数据量小,复杂度相对低,难以体会到性能的瓶颈。

初识ST05


首先,我们在一个REPORT程序中编写一段代码:

然后打开ST05

接下来按以下步骤操作:

1、Activate Trace

2、执行REPORT程序

3、Deactivate Trace

4、Display Trace,然后点执行,可以得到如下的界面

 这个界面展示了SQL的执行轨迹:

第二列,是每一条SQL的执行时间;

对象名列,是对应的表或视图;

最后一列,是相应的SQL语句。

初识执行计划


选中上图中表AFPO OPEN操作的行,点击工具栏上的”Explain”按钮(F9),可以得到SQL的执行计划。

其中1、2、3为SQL执行时的执行顺序。

步骤1中的AFPO~2,代表的是AFPO的索引2,该索引包括客户端和PROJN两个字段。

点击1下面的Access Predicates,可以看到

即,第一步访问AFPO表时,用的就是AFPO~2这个索引。

步骤2是根据步骤1得到的ROWID去AFPO获取数据,步骤3不用管它。

多个查询条件的执行计划


换一段代码

(在MSEG表中对BUDAT_MKPF新建了索引,索引名是Z05)

在我目前的项目上,这个SQL在开发机上执行的很快,到了生产机却执行的异常慢。通过ST05监测其执行轨迹,发现结果如下:

  • 在开发机上,第一步是先根据budat_mkpf Access,再根据werksbwart filter

  • 在生产机上,第一步是先根据werksbwart Access,再根据budat_mkpf filter

要解决这个问题并不麻烦,只需要通过HINTS人工指定索引即可(上一期也提到了),即:

%_HINTS ORACLE ‘INDEX(MSEG “MSEG~Z05”)’

(第一个MSEG可以不加引号)

至于生产机为什么和开发机是不一样的SQL执行计划,这个我也不清楚。

据BASIS解释说,是ORACLE的统计分析的结果,导致了这样的SQL执行计划。

ORACLE认为它是最优的,但在执行时不一定总是最优的。

这时候就需要我们的人工干预,以快速解决这样的性能问题。

(一般情况下,ORACLE的自动优化都是没太大问题的,但我在这里想说的是,我们要掌握一个快速解决处理的办法,以备不时之需)

表关联的执行计划


代码如下

执行计划如下

可以看到,多个表关联时,在图片最上面的SQL STATEMENT中出现了T_00、T_01,它们是参与JOIN的表的别名

因此,在表关联时,指定索引的方式与只查询一个表时略有不同,格式如下:

%_HINTS ORACLE ‘INDEX(T_00 “MSEG~OIB”)’

进一步分析


在此例中,大家也可以看到:

第一步,执行的是MSEG~Z11的索引(自建的索引),这个索引包含的内容是工厂和移动类型;

第二步,是按客户端过滤数据;

第三步,执行的是MKPF~0这个索引(~0是一个表的主键索引),它包含的内容是MKPF的主键字段,因为MSEG和MKPF进行了关联;

第四步,是按MKPF的BUDAT过滤数据。

(这是我在我的开发系统的测试结果,大家也可以自己测一下这个代码,应该有很多人跟我是一样的测试结果)

我们可以想象,如果数据很多的话,我们是根据工厂和261做第一步更快,还是根据一个月的日期做第一步更快?肯定是后者啊!

那怎么办呢?按照上面的方式指定索引吗?加上代码

%_HINTS ORACLE 'INDEX("T_01" "MKPF~BUD")'

然后试试,结果如下:

第一步、第二步没有变化,第三步变了。

没有达到预期的希望先ACCESS表MKPF的效果。

那我们把MKPF和MSEG关联的顺序颠倒一下可以吗?你试过之后发现依然不行。

怎么办呢?ORACLE为什么不按我希望的顺序执行呢?

于是我开始翻资料,查找“ORACLE指定查询顺序”的关键字,没找到原因,却最终得到了以下的处理办法:

 我把MKPF写在MSEG之前,并且指定HINTS ordered,使SQL执行计划按表出现的顺序执行。

接下来是它的执行计划分析:

OK!!这太棒了!!

这就是我们想要的结果了!!

案例与实际应用


下面这两个案例,都是我在运维项目上遇到的实际案例。

案例1


SQL语句如下

SELECT

afpo~projn

aufk~auart

afko~aufpl

prps~post1

FROM afpo

INNER JOIN aufk ON aufk~aufnr = afpo~aufnr

INNER JOIN afko ON afko~aufnr = aufk~aufnr

INNER JOIN prps ON prps~pspnr = afpo~projn

WHERE afpo~prps IN (....).

IN的内容较小时,执行没有问题,但是超过100条时,ST05的执行轨迹如下:

第一步是PRPS的ACCESS

第四步是AUFK的ACCESS FULL(全表扫描),非常耗时

第五步才是AFPO的Z03索引

(Z03是我这里PROJN的索引,系统中有标准的AFPO~2索引,我也不清楚为什么之前的顾问建了个多余的索引)

(大家如果写同样的程序,可能不会遇到跟我同样的问题)

这个SQL的执行速度超慢,大约5-10分钟

我一个表一个表的手动查询,都用不了2分钟的啊。

分析一下,这个很明显就是ORACLE自动确定的执行顺序出了问题(至于怎么),所以我就在后面加了ordered的hints,之后不到2秒钟,结果就出来了。

案例2


代码如下

其中GT_ALV中只有一条记录,根据其记录在PRPS可以找到18条数据,进而在AFVC中找到4条数据,最后根据AFVC的4条数据查询COSP的内容。

然而,它在生产系统的执行轨迹是这样的:

它按照顺序PRPS-AFVC-COSP的顺序执行,但是COSP时却意外的ACCESS FULL,看看吓人的CPU-Costs和IO-Costs吧,有没有要解决掉的冲动?

动手吧,因为它同样很简单,指定COSP的索引COSP~1即可(INDEX(T_02 "COSP~1")),COSP~1的第一个字段就是OBJNR。

结果当然也是很快的,一瞬间,就查询出来了。

写在最后


利用indexordered这两个hints,可能还是无法完全解决我们遇到的问题。除此之外,hints家族中还有leading(指定首先访问的表)、use_nl(nested loop的join方式)、use_hash(hash join的方式)等。

对于oracle,我懂的也不多,这几个hints怎么用,大家还是自己上网了解一下吧,网上的Oracle大神数不胜数,随便支点招就够我们abaper用的了。


IOS/ANDROID用户打赏——赞赏码

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,427评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,551评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,747评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,939评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,955评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,737评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,448评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,352评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,834评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,992评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,133评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,815评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,477评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,022评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,147评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,398评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,077评论 2 355

推荐阅读更多精彩内容