Post by "GaryYou", 2007-05-10, 17:11
-----------------------------------------------------
- 两重循环的性能问题
- 问题
在一个Grid上,有3万行数据需要被锁定,其中一部分数据有父子关系。一个父可以有多个子,但是一个子只能有1个父。当我们锁定一个父时,必须将所有的子也同时锁定。我们用parent来代表父行,用child来代表子行。其中,parent和child都有一个属性ItemID,而child有一个属性叫做ParentID,指向parent的ItemID。3万行数据中,有1万个父,1万个子。 - 原始方案
每拿到一个父,通过循环,找到它的每一个子,同时锁定找到的子。
代码:- For each parent as row in parents
- For each child as row in children
- If child.parentid=parent.itemid
- ‘进行子的锁定操作
- End if
- Next
- Next
复制代码 那么,以上循环的执行次数为:1万*1万=1亿,执行时间可能需要1分钟左右。 - 优化方案
不通过父找子,而是通过子找父,查找的时候也不用循环来查找,而是通过datatable的find方法进行查找。实现步骤如下:
首先,创建包含所有父的datatable,该表以ItemID为主键- For each parent as row in parents
- parentTable.AddRow(row)
- Next
复制代码 然后,进行子找父的操作。- For each child as row in children
- If not parentTable.rows.find(child.parentid) is nothing
- ‘子找到了父,进行子的锁定操作
- End if
- Next
复制代码 由于DataTable的Find方法执行的高效,通过上述的方式,最终执行时间控制在5秒以内。 - 结论
使用DataTable的Find方法,有时可以解决多重循环的性能问题。
- 关于C1FlexGrid的大数据量行的删除。
- 问题
在C1FlexGrid,有3万行数据需要被删除,但是这3万行数据不是连续的。 - 原始方案
- For each row as C1FlexGridRow in deletedRows
- Grid.rows.remove(row.Index)
- Next
复制代码 需要时间2分钟 - 优化方案
先记录要删除行的index- For each row as C1FlexGridRow in deletedRows
- deleteIndexs.add(row.Index)
- Next
复制代码 再从后往前删除行- For I as integer =deleteIndexs.count-1 to 0 step -1
- Grid.rows.remove(deleteIndexs(i))
- Next
复制代码 执行时间,5秒以内 - 总结
C1FlexGridRow的Index属性,要小心使用。如果有行被删除,然后再使用该属性,其值可能需要进行集合的遍历才能得出,所以会有性能问题。
- 关于类型转换的问题
- 背景
有一个class名叫RejectItem,它有一个属性叫RejectDate - 原始代码
- ‘ rejectList为ArrayList
- If rejectList(i).rejectDate>”#1/1/2006#”
- ‘ 内部操作
- End if
复制代码 - 优化代码
- If Ctype(rejectList(i),RejectItem).RejectDate>”#1/1/2006#”
- ‘ 内部操作
- End if
复制代码 使用该方式,性能可以提高一个数量级。 - 总结
Object对象,通过“object.xxx”的方式使用其属性或方法,即使属性方法不存在,编译的时候也不会出错,只是运行时会出错。如果使用的属性或方法存在,那么通过这种方法使用,虽然不会出错但是其运行效率会大大降低。
- 灵活运用表约束检查
- 背景
1件资产,存入数据库,需要用到11个表。其中一个表为基本信息表,其余表都和它有外键约束关系。
现在,我们要向系统录入大数据量的资产信息,比如1万件资产。那么,相应的,我们就要录入数据库记录几十万行。 - 原始方案
按照普通模式,一条资产一条资产的往数据库写入,每写一条资产信息,都要进行数据库外键约束的检查。这样的方式,执行速度较慢。 - 优化方案
将1万件资产分批,比如100件资产一批,一批资产进行一回录入操作。
每一批资产数据,首先通过CODE验证的方式,检查有外键约束的字段是否合法,然后才进行数据插入。
在插入数据之前,通过“NOCHECK”语句,关闭相关资产表的外键约束检查;
然后再插入资产信息;最后通过“CHECK”语句,再打开相关资产表的外键约束检查。
通过以上的操作方式,可让资产信息的录入速度提高5倍左右。 - 总结
外键约束输入可以保证录入数据的完整性,但是却牺牲了录入性能。对于大数据量的数据录入,这个外键约束将会极大的降低性能。
我们可以通过CODE验证的方式,保证传入数据的外键约束完整性,而不是使用数据库自身的外键约束机制来进行检查。
- 高效使用系统设置信息
- 背景
资产在作减价尝却的时候,需要得到一个尝却率信息列表,对应于数据库中的上百行记录。 - 原始方案
有一个接口,返回的就是尝却率信息,不过内部通过数据库查询实现。
如果有1000个资产,每个资产都需要进行减价尝却,为了获得尝却率信息,那么就要进行1000次的数据库查询。 - 优化方案
取一次尝却率信息,然后进行将其作为全局变量暂存或是作为参数传递给需要的方法。1000件资产,只需1次尝却率信息的数据库查询。 - 总结
对于数据的批量处理,如果需要用到系统设置信息,必须做到一批数据取一次设置信息,而不是每条数据都去取一次设置信息。
|
|