news 2026/8/23 8:12:11

064、SQL跟踪与性能分析(ST05)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
064、SQL跟踪与性能分析(ST05)

上个月,客户一个电话把我从午睡里拽了出来。说某个Z报表跑了一个小时还没出数,IT部门的人已经急得嘴上起泡。我打开那台测试机,用SE80把主流程翻了一遍,代码逻辑不算绕,循环里的SELECT也带了索引,怎么看都觉得不能这么慢。数据量?表才二十几万行。那问题出在哪?我只好祭出ST05。

ST05是ABAP里最常用的SQL跟踪工具,事务代码就叫ST05。它的作用说白了就是把你指定的用户、指定的时间段内,所有发送到数据库的SQL语句原封不动地记录下来。有人说“原封不动”不完全准确,至少能让你看到数据库真正执行的语句,而不是你在ABAP里写的那句OPEN SQL。这很重要,因为遇到隐式转换、缓冲失效、或者优化器抽风的时候,你根本不知道数据库那边做了什么妖。先不说原理,直接讲怎么用。

在命令框里输入ST05,进去后界面很简洁,有几个复选框,什么“SQL跟踪”“锁跟踪”“RFC跟踪”之类的。咱们日常用得最多的就是SQL跟踪,其他先别勾,勾多了日志文件会爆炸,光清理就能浪费你半天时间。然后指定跟踪对象,默认情况下是当前用户,也可以输入其他用户的用户名。我一般直接保持当前用户,因为我要去运行那个报表,用同一个会话最方便。接着点那个“开启跟踪”的按钮,像录音机一样,从这一刻起,数据库语句就开始被记录进去了。

开了跟踪之后,马上打开你要分析的ABAP程序,跑一小段。这里有个很重要的经验:别傻乎乎地等整个报表跑完再关,那样会用巨大的跟踪文件把系统拖死。我通常是执行程序后,等上十秒二十秒,看看到达某个关键节点,或者直接预选一小部分数据就停,然后立刻回到ST05点“关闭跟踪”。你要是忘了关,跟踪会一直开着,系统会越来越慢,最后所有用户的查询都排着队等你,那场面真的不太优雅。

关掉跟踪之后,点上面的“列表”按钮,或者“分析”也行,就能看到刚才记录的一堆数据库操作。界面分两大部分:左边是表名,右边是操作类型和统计信息。表名下面能看到SELECT、INSERT、UPDATE、DELETE各自有多少次,总共花了多少时间。别一上来就看最上面的,先按“耗时”排序。通常问题最严重的那条SQL就在第一屏。

我那个客户的问题就是这么暴露的。跟踪结果里有一条SELECT SINGLE出现了1600多次,单次平均时间0.03秒,累加起来就有48分钟。语句是:

DATA: lv_code TYPE char10. lv_code = lv_str. SELECT SINGLE * FROM zhead WHERE zcode = lv_code AND zflag = 'X'.

我盯着这句愣了三秒。zcode字段上明明有索引,zflag也是索引列的第二部分,理论上走索引只要几毫秒。为什么数据库傻乎乎地全表扫?我顺手在ST05里选中那条语句,点了一下“执行计划”,结果看到索引被忽略了,扫描方式变成了“FULL TABLE SCAN”。原因很快被揪了出来:我那个LV_CODE变量定义了CHAR10,而数据库表字段ZCODE是NUMC10。ABAP的Open SQL在语法检查时不会报错,运行时SQL被转换后,数据库层面为了比较不同类型,可能会隐式地对字段做转换。这个转换一动,索引就废了。解决方案也简单,直接让变量类型跟着表字段走:

DATA: lv_code TYPE zhead-zcode. " 用这种定义方式,类型天然匹配,别再自作聪明写CHAR10了 lv_code = lv_str. SELECT SINGLE * FROM zhead WHERE zcode = lv_code AND zflag = 'X'.

改完之后,这条语句从单次0.03秒降到0.0001秒,整个报表跑完不到两分钟。客户觉得我很神,其实都是ST05的功劳。

再举一个我看到过的经典场景。某同事写了一个程序,为了追求效率,用FOR ALL ENTRIES把一个内表作为查询条件去数据库捞数据,思路没问题,但他在查询完之后,又在一个内表循环里写了一句SELECT。ST05一开,发现数据库被访问了上万次。每一个循环里的SELECT看着都走索引,但架不住一万次啊。更隐蔽的是,FOR ALL ENTRIES本身会扩展成一条很长的SQL,如果内表数据特别多,生成的SQL语句可能会超长,数据库解析都会卡。ST05的列表里能看到SQL语句的文本长度,好几个字段我就见过几KB甚至几十KB的。遇到这种情况,我的习惯是用JOIN替代一部分FOR ALL ENTRIES,或者把大内表拆成几个小批次处理,别一口气塞进去。

ST05还能帮你看ABAP缓冲是否生效。如果某个表开启了ABAP缓冲,那么同一会话内重复读取的数据可能直接从应用服务器缓存里拿,数据库那边根本不会被访问。在ST05的跟踪结果里,每个操作会有“直达数据库”还是“缓冲读取”之类的标记。如果你发现一个应该命中缓冲的配置表,每次都在跟数据库打交道,那可能缓冲设置没生效,或者语句的WHERE条件不符合缓冲特性,比如用了非主键字段查询,缓冲机制直接绕过。这个坑在经常读取的自定义表上特别常见,动不动就拖慢整体响应。

有人会问,我用SE30看事务码的运行时,不也能看到时间吗?SE30看到的是程序在应用服务器上的CPU时间以及个部分耗时,但SQL层面到底哪条语句垃圾,它没有ST05这么细。ST05聚焦于数据库交互,能直接看到SQL文本、执行次数、花费的数据库时间,以及执行计划。两个工具配合起来用,能快速定位到性能问题是出在应用逻辑还是数据库访问。我调性能的基本套路是:先用SE30跑一遍,找到总耗时最高的那一小段,再用ST05单独跟踪这一段,精确到SQL。

用ST05有个注意点:生产系统上千万别随便全用户跟踪。开启跟踪本身会对数据库通信产生额外开销,如果库的数据量一大,跟踪文件会把磁盘写满,严重时直接宕机。我一般只在开发或者质量系统上折腾,生产上有问题,我宁可在非高峰时段只跟踪自己那个客户端进程。还有一点,跟踪结果看完就关,别一直开着。

另外说说执行计划。ST05里选中一条SQL后,有个“执行计划”的按钮,点开能看到数据库优化器选择的访问路径,走没走索引一目了然。有些版本还可以显示具体使用的索引名。这个功能是分析的关键,不要只盯着时间。一条SQL慢了,先看执行计划,如果显示索引没走,就检查WHERE条件的字段类型、函数包裹、OR条件、NULL判断这些常见的索引杀手。如果你改了SQL,再重新跑一遍跟踪,对比执行计划的变化,确保优化起作用了。

说到函数包裹,程序员有个不好的习惯:喜欢在条件里写“TO_UPPER(字段) = 变量”或者“SUBSTR(字段, 1, 2) = ‘AB’”,尤其从其他语言转过来的朋友。这种写法在ABAP里也能跑,但一旦对索引字段用了函数,数据库就没法走索引。ST05的执行计划会诚实地告诉你结果。如果非要这么查,就得考虑添加函数索引之类的方法,但不同数据库支持情况不一样。最稳妥的还是把数据整理好,让查询条件不带函数。

还有一个小技巧,ST05的跟踪列表一般都支持按列排序,你把鼠标点到“总计时间”那一列的标题上,点一下,让它按从大到小排序,所有高耗时的SQL就自动排到上面了。有些版本可能需要右键选择排序方式,反正万变不离其宗。找出耗时TOP5或者TOP10,逐个击破,优化效率比盲调高十倍不止。

我个人习惯是每次优化完,把ST05的结果导出成文本文件,带上当时的日期和程序名,放到项目共享目录里。这样过几个月回来,还能知道当初为什么这么改,比截图舒服多了,文本能搜历史记录。截图虽然直观,但没法检索,而且里面包含数据库表名和SQL语句,发给别人看还得打马赛克。文本导出的时候注意选只导出当前跟踪,别把整个系统日志导出来。

回到开头的案例,当我用ST05揪出那个类型不匹配的问题后,同事还一脸不信,说这也能影响性能?我直接把ST05里执行计划前后两张截图放在一起——好吧不能截图,但即使没有图,数据库执行计划里那个“FULL TABLE SCAN”是无法辩驳的。所以这篇里面所有说到的界面细节,你只要打开ST05,实际操作一遍,就全明白了。

好了,这篇关于SQL跟踪与性能分析的内容就到这儿。ST05不是那种花里胡哨的工具,界面也谈不上精美,但它就像一把手术刀,精准地切开数据库访问的皮肤,让你看到真正的病灶。下一篇我打算聊聊SE30运行时分析,或者如果有人想听ABAP调试器里那些不为人知的用法,也可以安排。评论区见吧。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/23 8:11:07

均匀随机相位下正弦信号幅度分布:从概率密度到工程应用

1. 从一个看似简单的问题开始最近在整理一些数学基础时,重新审视了一个非常经典的问题:正弦函数y sin(x)的概率分布。乍一看,这似乎是个纯理论推导,甚至有些“书呆子气”。但如果你从事信号处理、通信系统仿真、蒙特卡洛方法应用…

作者头像 李华
网站建设 2026/8/23 8:05:48

AI专利申请怎么写技术交底书

一、AI辅助发明的技术交底书,比传统发明多了一件事传统发明的技术交底书要写清楚3件事:技术问题、技术方案、技术效果。AI辅助发明的技术交底书要多写一件事:你对技术方案作出了什么实质性贡献——AI做了什么,你做了什么。为什么多…

作者头像 李华
网站建设 2026/8/23 8:05:33

Vue+Flask求职推荐系统:Apriori算法优化人岗匹配

1. 项目概述与核心价值 这个基于VueFlask技术栈的求职推荐系统,本质上是通过数据挖掘技术解决人岗匹配的效率问题。我在人力资源科技领域做了8年SaaS产品开发,发现传统招聘平台最大的痛点就是"简历海投"和"岗位轰炸"——求职者盲目投…

作者头像 李华
网站建设 2026/8/23 8:01:55

C++模板分离编译问题解析:从链接错误到模板特化实战

1. 从一次编译报错说起:为什么我的模板函数链接失败了? 最近在重构一个C项目时,我又一次掉进了那个熟悉的“坑”里。场景是这样的:我有一个通用的日志工具类,里面用到了函数模板来处理不同类型的日志格式化。为了代码结…

作者头像 李华
网站建设 2026/8/23 7:58:20

华为杯数学建模竞赛全流程实战指南:从组队到论文的避坑经验

1. 项目概述:一场硬核的“马拉松”式智力竞赛 “华为杯”中国研究生数学建模竞赛,这个名字在研究生圈子里,尤其是理工科领域,分量相当重。它不是一次简单的考试,而是一场为期四天、需要团队协作、脑力与体力双重拉锯的…

作者头像 李华
网站建设 2026/8/23 7:52:37

PySpark岭回归实战:大数据场景下的线性模型调优与避坑指南

1. 项目概述:从数据湖到回归洞察 如果你正在处理海量的数据,并且希望从中挖掘出预测性的规律,那么PySpark的 pyspark.mllib.regression 模块绝对是你工具箱里的利器。尤其是在处理那些动辄GB、TB级别的结构化或半结构化数据时,传…

作者头像 李华