1.为图方便写代码,写SQL的时候,直接在有索引的列上直接用函数
举个例子:销售单上销售日期这个列上键有所有,要根据年和月2个参数来查询某个月的销售单数据,很多就是这样写的:以MS-SQL为例
- select * from 销售单 where year(销售日期)=${年份} and month(销售日期)=${月份}
复制代码
其实这样会导致索引失效,如果销售单这个表上的数据比较多,那么执行就会非常慢
正确的写法:改变思路,在参数上执行计算,比方说查询2017年10月份的,转换成销售日期>='2017-10-01' and 销售日期<'2017-11-01' 这种形式
- 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万条单据,某个报表要按地区进行统计。
错误的做法:- select * from 销售单 where 销售日期 >= '2017-10-01' and 销售日期 < '2017-11-01'
复制代码 --返回50万条记录
正确的做法:
- select 地区,sum(销售金额) as 销售金额 from 销售单 where 销售日期 >= '2017-10-01' and 销售日期 < '2017-11-01' group by 地区
复制代码 --有多少个门店返回多少条记录
这样能减少数据从数据库返回到报表服务器的I/O开销
5.在报表数据多的时候,做SQL注入查询。仍然以销售单为例,比方说销售单上有客户ID,没有客户地址,客户地址存在客户信息表上,我们需要做一个销售单明细报表,上面要有客户地址,有的人会这样写来获取客户地址:
在单元格中设置公式
- =sql("销售数据","select 客户地址 from 客户信息 where 客户ID = '"+B3+"'",1,1)
复制代码
这样的做法会导致B3单元格扩展多少次,这个SQL脚本就会执行多少次,之前我有个报表用类似的方法来写,导致一个返回几千条数据的报表,执行了10几分钟还没执行完。
正确的做法是:尽量在SQL中进行关联,而不是在FR设计器中用条件过滤或者公式去关联取数
|