功夫都在报表外-漫谈报表性能优化

2023-12-12 02:38

本文主要是介绍功夫都在报表外-漫谈报表性能优化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第3期:封面图片

应用系统中的报表,作为面向业务用户的窗口,其性能一直被高度关注。用户输入参数后都希望立即就能看到统计查询结果,等个十几二十秒还能接受,等到三五分钟的用户体验就非常恶劣了。

那么,报表为什么会慢,又应当从哪里入手进行性能调优呢?

数据准备

当前应用中的报表大都用报表工具开发,当报表响应太慢时,不明就里的用户就会把矛头指向使用报表工具的开发人员或者报表工具厂商。其实,大多数情况报表的慢只是个表现,背后的原因是数据准备太慢,在数据进入报表环节之前就已经慢了,这时再去优化报表开发或压迫报表工具并没有用处。

报表是给人看的,人类视力限制不可能查看过多数据,也就没有大数据的呈现需求。报表工具为了直观而采用的状态式计算模型,也不适合实现有复杂过程的计算。报表环节不应当也无能力解决大数据和复杂计算问题,只要处理小数据的摆位和简单计算,这不会耗用太多时间。

八成左右的报表慢是因为数据准备造成的。报表呈现的数据量虽然小,但涉及的原始数据量可能巨大,把大数据汇总和过滤成小数据需要很长时间;复杂计算也是类似,主要时间消耗在数据准备阶段。数据准备的优化是报表提速的关键。

1. 优化数据准备代码:一般是SQL(或存储过程),某些时候是应用程序的代码(涉及非数据库或多数据库时);

2. 数据库扩容:数据量大,代码不能再优化时,还可以扩容数据库,比如采用集群方案;

3. 采用高性能计算引擎:传统数据库在实现某些运算时性能较差或成本太高,可以更换为其它计算机制;

数据计算

报表环节本身计算性能差的情况相对少,但也是有的。

一个典型的场景是多源关联报表,即把多个二维数据集按某个主键对齐呈现,有时可能还需要分组汇总。报表工具要求把计算都写进单元格,这样只能用数据集过滤来描述本格和其它数据集的关联,类似ds2.select(ID==ds1.ID)的表达式。这个运算复杂度是平方级的,在数据量不大时也无所谓,但数据量稍大(几千行)且涉及数据集较多时,性能就会急剧下降,从几秒到几十分钟都有可能。

如果我们把这个运算移到报表外,在数据准备阶段时处理,就可以大幅度提升性能。如果数据来自同一个数据库,那么用SQL写JOIN语句就可以了,如果数据集来自多库或者希望减轻数据库计算压力,也可以在外部实现HASH JOIN算法。HASH JOIN算法可以整体地看待几个数据集,效率比报表工具采用的过滤式关联要高得多,几千行规模时几乎是零等待。

报表计算性能差虽然发生在报表环节本身,但经常却要在报表外去解决。

其它类似场景还有,如带部分明细行的分组汇总表,表现出来是由于报表环节处理数据量大导致运算变慢,而解决方法也是把运算移到报表外。

数据传输

报表还有个慢的瓶颈在于数据传输。

目前很多应用都是J2EE架构的,采用的报表工具也是Java写的,这时访问数据库都要用JDBC接口。然而,某些常用数据库的JDBC驱动性能很差(这里就不点名了),取出数据量稍多(几万行)时就会有明显的等待感。这就导致一个无奈的现象:数据库压力很轻计算很快,报表端计算也不算复杂,但报表仍然很慢。

无论应用开发商还是报表工具厂商都没办法改变数据库的JDBC驱动,只能在外面想办法。经过多次实验,我们发现启用多线程并行取数就能获得数倍的性能(前提是数据库负担轻)。但是,目前还没有报表工具直接提供了并行取数的功能(由于数据分段方法和数据库及取数语法相关,需要代码控制,也不容易做成报表功能),这个方案仍然要在报表环节外的数据准备阶段来实施。

可控缓存

把近期访问过的报表缓存起来,短时间内再次访问同参数的报表时可以不必计算而直接返回,显然这能改善用户体验。很多报表工具也都提供有缓存功能,不过并不细致,缓存只能针对整个报表,而且各个报表的缓存是无关的。在报表外下点功夫可以实现控制力度更细致的缓存功能:

1. 部分缓存。有些报表、特别是常见的多源报表,其中大部分数据相对稳定(历史数据),只有小部分数据时效性差(当期数据)。而整个报表的缓存的有效期只能以较短的为准,这样会导致报表经常被重算。如果能只缓存部分数据,就能延长这部分缓存的生命期,从而减少计算量。

2. 缓存复用。不同的报表可能引用到同样的数据,而互相无关的报表缓存机制则会迫使这些报表多次重复计算同样的数据。如果能让某个报表引用到其它报表已经计算出来的缓存数据,也能有效减少计算量。

这些复杂的缓存控制需要编写代码来实现,不容易在报表工具中提供,但在可编程的数据准备阶段实施却相对容易。

清单列表

前面说过,报表和大数据的直接关系并不大。甚至可以说老是喊大数据报表的厂商多半是忽悠。

不过有一种清单列表确实是大数据报表。清单列表在金融行业经常碰到,把一段时间的交易清单列出来。其特点是数据量特别大,可能会有几千上万页,不过计算会相对简单,经常只是罗列,最多有些按页按组的汇总。

报表工具为了处理灵活的格间运算,一般都会采用全内存方式。这样,把清单列表加载进报表工具时,会大概率出现内存溢出;而且太大数据量全部取出并加载也需要很长时间,用户难以容忍。

容易想到的办法是边读取边呈现,每次只呈现一页,不会溢出;读满一页后立即呈现,用户不会有太强的等待感。数据库都提供有游标可以逐步读出数据,但用户可能在前端翻页,这还需要高速随机按页(行)取数的能力。数据库就没有这种接口了,用条件过滤取数不仅很慢,而且还由于数据可能仍在更新而不能保证报表在生命周期内的数据一致性。

结果还是要在数据准备阶段解决。两个异步线程:一个负责从数据库取数并缓存到外存(假定数据量大内存装不下),另一个接受前端请求从缓存中按页(行)取出数据返回。

这篇关于功夫都在报表外-漫谈报表性能优化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/482943

相关文章

小白也能轻松上手! 路由器设置优化指南

《小白也能轻松上手!路由器设置优化指南》在日常生活中,我们常常会遇到WiFi网速慢的问题,这主要受到三个方面的影响,首要原因是WiFi产品的配置优化不合理,其次是硬件性能的不足,以及宽带线路本身的质... 在数字化时代,网络已成为生活必需品,追剧、游戏、办公、学习都离不开稳定高速的网络。但很多人面对新路由器

Zabbix在MySQL性能监控方面的运用及最佳实践记录

《Zabbix在MySQL性能监控方面的运用及最佳实践记录》Zabbix通过自定义脚本和内置模板监控MySQL核心指标(连接、查询、资源、复制),支持自动发现多实例及告警通知,结合可视化仪表盘,可有效... 目录一、核心监控指标及配置1. 关键监控指标示例2. 配置方法二、自动发现与多实例管理1. 实践步骤

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

MyBatisPlus如何优化千万级数据的CRUD

《MyBatisPlus如何优化千万级数据的CRUD》最近负责的一个项目,数据库表量级破千万,每次执行CRUD都像走钢丝,稍有不慎就引起数据库报警,本文就结合这个项目的实战经验,聊聊MyBatisPl... 目录背景一、MyBATis Plus 简介二、千万级数据的挑战三、优化 CRUD 的关键策略1. 查

JVisualVM之Java性能监控与调优利器详解

《JVisualVM之Java性能监控与调优利器详解》本文将详细介绍JVisualVM的使用方法,并结合实际案例展示如何利用它进行性能调优,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录1. JVisualVM简介2. JVisualVM的安装与启动2.1 启动JVisualVM2

Java使用MethodHandle来替代反射,提高性能问题

《Java使用MethodHandle来替代反射,提高性能问题》:本文主要介绍Java使用MethodHandle来替代反射,提高性能问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录一、认识MethodHandle1、简介2、使用方式3、与反射的区别二、示例1、基本使用2、(重要)

SpringBoot中HTTP连接池的配置与优化

《SpringBoot中HTTP连接池的配置与优化》这篇文章主要为大家详细介绍了SpringBoot中HTTP连接池的配置与优化的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、HTTP连接池的核心价值二、Spring Boot集成方案方案1:Apache HttpCl