大清单报表应当怎么做?

简介:

sjjt-210

在数据查询时,有时会碰到数据量很大的清单报表。用户输入的查询条件很宽泛,可能会从数据库中查出几百上千万行甚至过亿的记录。如果等着把这些记录全部检索出来再生成报表呈现,那需要很长时间,用户体验恶劣;而且报表一般采用内存运算机制,大多数情况下也装不下这么多数据。所以,我们一般都是使用分页呈现的方式,尽量快速地呈现出第一页,然后可以随意翻页显示,每次只显示一页,也不会造成内存溢出。


那么,一般的报表工具或BI系统都是怎么实现这一机制的呢?

绝大多数产品都是使用数据库分页的方法来做的。

具体来讲,就是利用数据库提供的返回指定行号范围内记录的语法。界面端根据当前页号计算出行号范围(每页显示固定行数)作为参数拼入SQL中,数据库就会只返回当前页的记录,从而实现分页呈现的效果。

这样做,会有两个问题:

1. 翻页时效率较差

用这种办法呈现出第一页来一般都会比较快,但如果向后翻页时,这个原始取数的SQL会被再次执行,并且将前面页涉及的记录跳过。有些数据库没有OFFSET关键字,就只能由界面端自行跳过这些数据(取出后丢弃),像ORACLE还需要用子查询产生一个序号才能再用序号做过滤,这些动作都会浪费时间,前几页还感觉不明显,但如果翻到的页号比较大时,就会有等待感了。

2. 可能出现数据不一致

一般来说,每次按页取数时发出的SQL是独立的。这样,如果在两页取数之间数据库又有了插入删除动作,这时取出来的数据将是最新的,很可能和原来的页号匹配不上了。比如第1页取出20行记录后,在取第2页前,第1页的20行记录中被删除了1行,那么这时候取出来的第2页的第1行就会是原来的第22行记录,原来的第21行会落到第1页去了,要再倒翻页才能看到。如果基于这些数据做汇总统计,那会出现错误的结果。


还有一种不常用的方法。向数据库发出取数SQL生成游标,从中取出一页后呈现,但并不终止这个游标,要取下一页的时候再继续取数。这种方法能克服上述两个问题,不会发生不一致的现象,但绝大多数的数据库游标只能向后取数而不是倒回去,这样在界面上的表现就是只能向后翻页了,这一点很难向业务用户解释,所以很少用这种办法。

也可以是两种办法的结合,向后翻页时用后一种办法,一旦发生向前翻页时,则重新执行取数SQL。这样比每次分页取数的体验略好一些,但并没有根本上解决问题。


还有什么好办法呢?

把取数和呈现做现两个异步线程,取数线程发出SQL后就不断取出数据后缓存到本地存储中,呈现线程根据页数计算出行数到本地缓存中去获取数据显示。这样,只要已经取过的数据就能快速呈现,不会有等待感,还没取到的数据需要等待一下也是正常可理解的;而取数线程只涉及一句SQL,在数据库中是同一个事务,也不会有不一致的问题。这样,两个问题都能得到解决。不过这需要设计一种可以按行号随机访问记录的存储格式,不然要靠遍历把记录数出来,那反应仍然会很迟钝。

在当前数据库系统不直接支持这种机制时,只能是报表工具或BI系统受累自己写这些程序了,对于有大清单报表呈现需求的用户,就要认真考察这些功能点了。

相关文章
|
Java API
QLExpress功能清单
QLExpress从一开始就是从复杂的阿里电商业务系统出发,并且不断完善的脚本语言解析引擎框架,在不追求java语法的完整性的前提下(比如异常处理,foreach循环,lambda表达式,这些都是groovy是强项),定制了很多普遍存在的业务需求解决方案(比如变量解析,spring打通,函数封装,操作符定制,宏替换),同时在高性能、高并发、线程安全等方面也下足了功夫,久经考验。
20801 1
|
安全 Android开发 iOS开发
任务清单,我是这样记录日常工作的!
相信有很多老师都是一样,平时忙起来,很多事情都想不起了。临到上交的时间节点,又感觉手忙脚乱。
164 2
|
SQL Java 关系型数据库
从系统报表页面导出20w条数据到本地只用了4秒,我是如何做到的
最近有个学弟找到我,跟我描述了以下场景: 他们公司内部管理系统上有很多报表,报表数据都有分页显示,浏览的时候速度还可以。但是每个报表在导出时间窗口稍微大一点的数据时,就异常缓慢,有时候多人一起导出时还会出现堆溢出。 他知道是因为数据全部加载到jvm内存导致的堆溢出。所以只能对时间窗口做了限制。以避免因导出过数据过大而引起的堆溢出。最终拍脑袋定下个限制为:导出的数据时间窗口不能超过1个月。
|
BI 数据库
汇总报表怎么做,如何设计实现汇总报表?
汇总报表怎么做,如何设计实现汇总报表?
宜搭无代码实现物料数字仓库和自动采购系统展示
物料库存台账是企业数字化的一个核心需求,市面上常见的各种进销存和金蝶用友财务管理软件皆是围绕着仓库货物的销售、采购、入库、出库等物料流转流程设计的。但大部分软件依靠人工去计算库存空余和采购需求数量的计算,然后在将进出数据手工录入系统,进销存软件仅仅体现出一个数字记账功能。就是一个流水账!
531 1
宜搭无代码实现物料数字仓库和自动采购系统展示
|
数据采集 运维 算法
谈谈物料数据质量问题和提升路径
本文所谈的物料是指企业中所有物资、产品和服务的总和。从某种意义上说,物资是工业企业所占价值最大的一部分。
谈谈物料数据质量问题和提升路径
|
大数据 测试技术 开发者
项目分析_流程分析|学习笔记
快速学习项目分析_流程分析
126 0
项目分析_流程分析|学习笔记
|
BI 关系型数据库 数据库
银行业大数据量清单报表案例
银行数据查询业务中,经常会碰到数据量很大的清单报表。由于用户输入的查询条件可能很宽泛,因此会从数据库中查出几百上千万甚至过亿行的记录,比如银行流水记录;为了避免内存溢出,一般都会使用关系型数据库的分页机制来做,但结果往往也不尽人意;有些情况下甚至底层采用了非关系型数据库,这更会加剧了问题的复杂度。
1270 0
|
前端开发
15、【 商品管理模块开发】——后台获取商品详情功能开发及PropertiesUtil配置工具,DateTimeUtil时间处理工具开发
1、后台获取商品详情接口: 在上一篇文章所新建的ProudctManageController类中新建下面方法:*Controller: //获取商品详情接口 @RequestMapping("get_detail.
1069 0