我们的报表为什么会慢

楼主
我是社区第133825位番薯,欢迎点我头像关注我哦~
1.为图方便写代码,写SQL的时候,直接在有索引的列上直接用函数

举个例子:销售单上销售日期这个列上键有所有,要根据年和月2个参数来查询某个月的销售单数据,很多就是这样写的:以MS-SQL为例

  1. select * from 销售单 where year(销售日期)=${年份} and month(销售日期)=${月份}
复制代码

其实这样会导致索引失效,如果销售单这个表上的数据比较多,那么执行就会非常慢


正确的写法:改变思路,在参数上执行计算,比方说查询2017年10月份的,转换成
销售日期>='2017-10-01' and 销售日期<'2017-11-01'
这种形式
  1. select * from 销售单 where 销售日期 >= DATEADD(MONTH,${月份}-1,DATEADD(YEAR,${年份}-1900,'1900-01-01')) and 销售日期<DATEADD(MONTH,${月份},DATEADD(YEAR,${年份}-1900,'1900-01-01'))
复制代码

当然,关于用年月来计算日期,还有其他方法,这里不一一列举

2.设计数据集的时候,并不是遵循用多少数据取多少数据的原则,而是先把数据都拉过来,然后在设计器中设置条件过滤来获取想要的数据,我们应该检查数据集的结果是否有浪费的现象。数据集返回的结果,应该全部都能用在报表里面,尽量不要有冗余,其实这个问题,很多熟悉SQL的都会有意无意的这样做,比方说为了避免在存储过程中写过多的IF逻辑判断,然后取了一大堆的数据到临时表,然后根据某个参数的值把不符合条件的数据delete掉

3.设计数据集时,因为不太懂SQL,写了逻辑复杂、可读性差并且效率低下的SQL脚本,这个问题需要我们去好好学习一下SQL了

4.数据集返回的数据,应该先根据报表需要统计的粒度进行聚合运算,而不是直接返回原始数据,然后在报表里面去汇总,仍然以销售单为例,比方说销售单一个月有50万条单据,某个报表要按地区进行统计。

  错误的做法:
  1. select * from 销售单 where 销售日期 >= '2017-10-01' and 销售日期 < '2017-11-01'
复制代码
--返回50万条记录  

正确的做法:
  1. select 地区,sum(销售金额) as 销售金额 from 销售单 where 销售日期 >= '2017-10-01' and 销售日期 < '2017-11-01'  group by 地区
复制代码
--有多少个门店返回多少条记录


  这样能减少数据从数据库返回到报表服务器的I/O开销


5.在报表数据多的时候,做SQL注入查询。仍然以销售单为例,比方说销售单上有客户ID,没有客户地址,客户地址存在客户信息表上,我们需要做一个销售单明细报表,上面要有客户地址,有的人会这样写来获取客户地址:

在单元格中设置公式
  1. =sql("销售数据","select 客户地址 from 客户信息 where 客户ID = '"+B3+"'",1,1)
复制代码

这样的做法会导致B3单元格扩展多少次,这个SQL脚本就会执行多少次,之前我有个报表用类似的方法来写,导致一个返回几千条数据的报表,执行了10几分钟还没执行完。


正确的做法是:尽量在SQL中进行关联,而不是在FR设计器中用条件过滤或者公式去关联取数


分享扩散:
参与人数 +1 F豆 +100 理由
xzk1103 + 100 骚年,我看好你哦

查看全部评分

沙发
发表于 2018-5-17 15:08:16
帆软论坛“帖子排版技巧”快速进阶指南
http://bbs.fanruan.com/thread-101128-1-1.html
(出处: 帆软论坛)
板凳
发表于 2018-5-17 17:11:26
不错不错
地板
发表于 2018-5-18 08:25:12
写的太好了,感谢楼主
5楼
发表于 2018-5-18 09:08:29
点赞
6楼
发表于 2018-5-18 10:59:03
这种问题的大家应该都会遇到
7楼
发表于 2018-5-18 15:49:44
已提名精华帖,待论坛运营委员会评分后可评为精华帖,帆软论坛精华帖奖励计划http://bbs.fanruan.com/thread-91079-1-1.html
8楼
发表于 2018-5-18 18:02:03
9楼
发表于 2018-5-20 21:03:13
学习学习了
10楼
发表于 2018-5-28 13:24:48
第一个我比较喜欢
11楼
发表于 2018-6-1 16:16:36
楼主,既然你发了贴,并且被提名精华。这个问题就又必要探讨了哦,你的第2个观点是有问题的,从执行效率上来说,很少有服务器能大于数据库的,特别是一些设计很好的数据库。并且也有实际例子可以支撑这个观点,所以,数据宁愿从数据库取好,而应该尽量避免从前台再判断数据,这才是最好的办法。欢迎楼主进一步发表观点。
12楼
发表于 2018-8-17 14:33:51

写的太好了,感谢楼主
13楼
发表于 2019-1-2 08:38:49
14楼
发表于 2019-1-9 09:44:35
最后一点比较容易放错,想简单化,懒得写代码
15楼
发表于 2019-1-11 12:29:01
先学一手,后面多注意,感谢分享
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

返回顶部 返回列表