遇到一个datawindow执行效率的问题目的:源数据:一个datastore:C# codeselect medid,getdate() as appdate,
遇到一个datawindow执行效率的问题
目的:
源数据:一个datastore:
C# codeselect medid,getdate() as appdate,sum(number) as number from outsheet_detail where outsheetid in (select outsheetid from med_outsheet where ot_date>=dateadd(day,-30,getdate())) group by medid
扫描出一个月的药品用量,含有药品编码、药品数量和当前日期
目标数据:一个medapp表,medid,number和appdate字段对应的数据窗口。
通过把源数据检索到目标数据中。
方法:
1、我先用了一个按钮【生成】,里面写有生成datastore的语句(最开始未用字段getdate()的appdate字段),并用for循环的方法赋给目标数据窗口dw_1。
2、dw_1可以根据生成数据修改增加,因此为使数据具有可读性,通过一个函数来显示其它字段
C# codeglobal function string f_getmedinfo (string medid, string returncolumn);string returnvaluedecimal returnvalue2choose case returncolumn case 'medname' select medname into :returnvalue from medcoding where medid = :medid; case 'gg' select gg into :returnvalue from medcoding where medid = :medid; case 'unit' select unit into :returnvalue from medcoding where medid = :medid; case 'price' select price into :returnvalue2 from medcoding where medid = :medid; returnvalue = string(returnvalue2) case 'chandi' select chandi into :returnvalue from medcoding where medid = :medid;end choose return returnvalueend function
目标数据窗口中除编号、数量和日期外,通过compute字段显示了函数里的5个字段。
发现当数据超过4-5行后,对dw_1的操作会很慢。
于是我让datastore的数据在open事件中生成,又让其生成dateapp列,用rowscopy生成dw_1数据,仍发现速度很慢,考虑是不是因为函数的调用引起的慢。
希望得到的帮助:
请帮忙分析一下我的思路问题,看是不是函数原因,这种情况如何处理,把函数分成5个函数有没有用。
[解决办法]感觉楼主的设计思路有问题,你的这个函数对于每一条记录都要去执行5次SQL,分别取出5个字段的值,所以你与数据库交互的次数等于记录数乘以5,当记录数过多时会导致程序执行变慢。建议楼主改变源数据窗口的设计,将medcoding表的关连也加到数据窗口中,直接通过getitem去取得这5列的数据校为合适。
[解决办法]慢的原因在于:dw中的计算列使用了带SQL语句计算的全局函数
在dw中计算列并不是只在<1>添加数据行时才进行计算的
<2>当你滚动dw时,处于显示状态的计算列会重新计算
<3>当你移动窗口时,处于显示状态的计算列会重新计算
<4>当你移动其他窗口覆盖到该dw时,处于显示状态的计算列会重新计算
<5>当你将覆盖的窗口移开时,处于显示状态的计算列会重新计算
<6>当你删除行时,处于显示状态的计算列会重新计算
(以上情况数据窗口,会对所有当前处于显示状态的计算列进行重新计算)
<7>当你编辑dw数据时,当前行处于显示状态的计算列会重新计算
<8>当你将光标从非计算列移动到计算列时,计算列所处的行中所有处于显示状态的计算列都会重新计算2次
<9>当你将光标从计算列移动到计算列时,处于显示状态的所有计算列会依次重新计算1次,而目标行中所有处于显示状态的计算列都会额外重新计算2次
<10>当你将光标从计算列移动到非计算列时,所有处于显示状态的计算列都会重新计算1次
而你有5个计算列使用了含SQL的全局函数,这样一来你的dw与数据库的交互频率将会相当快,速度当然慢啦,如果你使用的数据库具有SQL执行跟踪功能,你可以自己跟踪一下
你这种情况,最好不要使用计算列,直接使用不更新的数据列,然后在medid列数据改变时,重新一次性获取相关信息,并setitem到当前行上对应的数据列上