数据加载分析

在BaskReport当中,为了方便我们查看报表在处理过程中各个环节的耗时情况,Windows下可在以预览页面中,通过快捷键Ctrl+Alt+Shift+Delete,四个功能键调出报表耗时信息窗口,如下图所示:

img

该窗口向我们展示了六项信息信息,我们从上至下逐个介绍。

编译报表耗时

该项目展示的是报表模版在修改完成后第一次运行时编译耗时情况。

用户在请求某个预览报表文件时,系统会首先在内存中检查当前模版对应的编译好的报表对象是否存在,如果不存在则到数据库中找到模版对应的XML数据,加载、编译并将编译好的报表对象缓存在内存当中;如果存在则检查当前报表对象对应的模版有没有修改,如果没有修改则直接采用该报表对象进行加载数据计算,此时这里的耗时就是0,否则则从数据库中重新加载报表模版XML并编译替换内存中的报表对象。

这里显示的就是报表模版编译成报表对象的耗时情况。

获取数据耗时

该项目展示的是报表模版中定义的各个数据集加载数据的耗时情况及具体的数据条数。

需要注意的是,如果定义了某个数据集,但该数据集在模版中又没有被用到,那么引擎会直接忽略该数据集,这里也就不会显示该数据集的信息。

报表计算耗时

这里展示的就是报表在加载数据后根据模版中定义的结构生成具体报表实例对象的耗时情况,如果报表结构较复杂,同时数据量也比较大(比如几十万,甚至上百万),那么这里显示的时长也就会比较大。

分页耗时

BaskReport因为计算的需要,它是在内存中对计算好的数据进行分页的,这里显示的就是分页耗时情况。

构建HTML耗时

本项目展示的是报表模版在计算好以后生成网页中需要展示的HTML时所花费的时间。

总耗时

也就是前面所有项目耗时总和。

需要重点关注的项目

对于我们使用者来说,最需要关注的就是获取数据耗时报表计算耗时

获取数据耗时

通过观察获取数据耗时项目下各个数据集的时长,如果发现某个数据集获取数据的时长过长,那就说明该数据集获取数据的途径可能需要优化,比如SQL语句需要优化、数据库服务器性能低下、连接数据库的网络不够通畅等。

除了前端耗时窗口外,服务端还会在数据加载完成后打印统一的日志,可直接从服务端日志定位各类数据集的耗时与失败原因。统一日志格式如下(成功日志为 DEBUG 级,默认不输出,需在日志配置中将相关包调为 DEBUG 才会打印;失败日志为 ERROR 级,始终输出):

成功(DEBUG 级):

数据集【{name}】加载数据完成,类型:{JDBC|API|Bean|Adapt},耗时:{ms}ms,数据条数:{count}

失败(ERROR 级):

数据集【{name}】加载数据失败,类型:{JDBC|API|Bean|Adapt},异常消息:{msg}

其中 类型 字段用于区分数据源类型(JDBC / API / Bean / Adapt),数据条数 与前端耗时窗口中的条数一致,便于交叉核对。API 数据集还会额外打印一行远程请求耗时:

数据集【{name}】API远程请求完成,URL:{url摘要},耗时:{ms}ms

若命中 API 内存缓存(未真正发起远程调用),则打印:

数据集【{name}】API远程请求命中缓存,跳过远程调用

⚠️ 以上统一日志需要 BaskReport / BaskServer 2.3.3+。更早版本中 API 仅有 DEBUG 级响应日志、Bean 与 Adapt 无任何耗时日志,无法直接从服务端日志定位。

JDBC 数据集

JDBC 执行日志示例如下(统一格式,含数据集名与数据条数):

数据集【员工明细】加载数据完成,类型:JDBC,耗时:12ms,数据条数:358
  • 如果 JDBC 查询耗时本身很长,说明慢在数据库侧,应优先排查 SQL 优化、数据库负载、索引、网络等问题;
  • 如果 JDBC 耗时很短,但报表获取数据耗时很长,说明问题出在报表引擎获取结果集之后的数据处理环节(结果集过大、类型转换复杂、模板内额外加工等),应重点检查数据集字段、参数绑定与模板逻辑。

服务端 SqlExecutor 仍保留原有的 DEBUG 级 SQL query executed successfully: ..., execution time: xxms(默认不输出),与上面的统一日志并存。

API 数据集的耗时查看

API 数据集的耗时分布在两个环节:

  1. HTTP 请求耗时(核心)ApiDatasetProducer 通过 HttpRequestClient(GET/POST)发起远程调用,耗时受 API 数据集上配置的 connectTimeout(连接超时)readTimeout(读取超时) 控制(这两个值在数据集的 content JSON 中设置)。接口响应慢时通常表现为请求长时间等待,甚至抛出超时异常。
  2. 响应解析耗时:拿到响应体后,getDatasByPath 会用 JsonPath 解析并按行追加 ROW_TAG 标记列;当响应体很大或 JSON 结构很复杂时,这一步也会变慢。

排查办法:

  • 先用 Ctrl+Alt+Shift+Delete 的「获取数据耗时」看该 API 数据集的整体耗时;
  • 再看服务端 DEBUG 日志中该数据集的 API远程请求完成,耗时:xxms 与整体 加载数据完成,类型:API,耗时:xxms(需将日志级别调为 DEBUG):
    • 远程请求耗时长 → 慢在远程接口侧,用 curl/Postman 单独打接口对比、或检查 connectTimeout/readTimeout 配置;
    • 远程请求很快、整体耗时却长 → 慢在 JsonPath 解析/数据转换,考虑让后端分页或只返回必要字段。
  • 异常时服务端会打印 ERROR 级统一失败日志 数据集【xxx】加载数据失败,类型:API,异常消息:...,可据此判断接口超时、URL 不可达或认证失败(原 API接口数据加载异常 日志仍保留)。

Bean 数据集的耗时查看

Bean 数据集由用户自定义业务方法(BeanDataset.getData(...))返回数据,引擎侧在调用前后自动计时并打印统一 DEBUG 日志(零侵入,无需改动用户业务代码):

数据集【用户列表】加载数据完成,类型:Bean,耗时:8ms,数据条数:42
  • 若耗时较长,说明慢在 getData() 内部业务逻辑(数据库查询、远程调用、复杂计算等),应排查该方法实现;
  • 异常时打印 数据集【xxx】加载数据失败,类型:Bean,异常消息:...

Adapt 数据源的耗时查看

Adapt 数据源通过 DataSourceServiceImpl.queryAdaptDataset 调用 AdaptLoader.load(...) 取数,引擎在调用前后自动计时并打印统一 DEBUG 日志:

数据集【销售输出节点】加载数据完成,类型:Adapt,耗时:33ms,数据条数:77
  • 若耗时较长,说明慢在 Adapt 取数流程(对应 baskadapt 模块的实现),应排查该 Adapt 输出节点 / 取数逻辑;
  • 异常时打印 数据集【xxx】加载数据失败,类型:Adapt,异常消息:...

报表计算耗时

该项目展示的就是报表在拿到数据后生成具体报表所花费的时长,该时长大小就是报表性能的核心体现。

results matching ""

    No results matching ""