以文本方式查看主题 - Foxtable(狐表) (http://foxtable.com/bbs/index.asp) -- 专家坐堂 (http://foxtable.com/bbs/list.asp?boardid=2) ---- [求助]二段代码差不多,但一条执行效率非常低下,请老师看看。 (http://foxtable.com/bbs/dispbbs.asp?boardid=2&id=75958) |
-- 作者:huangfanzi -- 发布时间:2015/10/18 19:36:00 -- [求助]二段代码差不多,但一条执行效率非常低下,请老师看看。 说明:集合drs的记录数有32670条 二段代码很类似,但不知为什么第二段代码效率这么低下,老师帮我看看,谢谢! 以下代码执行完用了40分钟。 Dim Result As DialogResult Result = MessageBox.Show("即将进行全表作业时间计算,是否执行?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) If Result = DialogResult.Yes Then Dim t1 As Date = Date.Now Dim sum As Double Dim tp As TimeSpan Forms("进度条独立窗口").Show \'打开进度条独立窗口 Dim p As WinForm.ProgressBar = Forms("进度条独立窗口").Controls("ProgressBar") \'定义进度条独立窗口中的进度条控件 Dim l As WinForm.Label = Forms("进度条独立窗口").Controls("Label1") \'定义进度条独立窗口中的Lable控件 Dim drs As List(Of DataRow) = _dt工序合并表.SQLSelect("","","记录标记2") \'按记录标记2排序以加快变量sum运算速度 If drs.Count > 0 Then For i As Integer = 0 To drs.Count - 1 l.Text = "计算中,当前进度: " & i+1 & " / " & drs.Count p.Maximum = drs.Count \'设置最大值 p.Minimum = 0 \'设置最小值 If i Mod 100 = 0 Then \'每运算100条更新一次投料量进度条 p.Value = i \'当前值为已经完成的行数 ElseIf i=drs.Count-1 \'当i为最大值减1时 p.Value = drs.Count \'当前值直接等于最大值 Forms("进度条独立窗口").Close End If If drs(i).IsNull("结束时间") Then drs(i)("作业分钟数") = 0 Else tp = drs(i)("结束时间") - drs(i)("起始时间") If i = 0 Then sum = _dt工序合并表.SQLCompute("Sum(重量)", "记录标记2 = \'" & drs(i)("记录标记2") & "\'" ) ElseIf drs(i)("记录标记2") <> drs(i-1)("记录标记2") Then sum = _dt工序合并表.SQLCompute("Sum(重量)", "记录标记2 = \'" & drs(i)("记录标记2") & "\'" ) End If drs(i)("作业分钟数") = tp.TotalSeconds()/60/sum * drs(i)("重量") End If Next _dt工序合并表.SQLUpdate(drs) End If MessageBox.Show("完成全表作业时间计算!耗时: " & (Date.Now - t1).TotalSeconds & "秒,请不要频繁操作.", "提示",MessageBoxButtons.ok, MessageBoxIcon.Information) End If 以下代码执行完用了21秒。 \'库存标记生成模块 Dim Result As DialogResult Result = MessageBox.Show("进行全表库存标记重算,大约耗时20秒钟,是否执行?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) If Result = DialogResult.Yes Then Dim t1 As Date = Date.Now Dim drs As List(Of DataRow) = _dt工序合并表.SQLSelect("","", "卷号,起始时间") \'指定母卷号计算 If drs.Count=1 Then drs(0)("库存标记") = True Else For i As Integer = 1 To drs.Count - 1 Dim p As WinForm.ProgressBar \'定义投料量进度条 Forms("进度条独立窗口").Show \'打开投料量进度条独立窗口 p = Forms("进度条独立窗口").Controls("ProgressBar") p.Maximum = drs.Count \'设置最大值 p.Minimum = 0 \'设置最小值 If i Mod 100 = 0 Then \'每运算100条更新一次投料量进度条 p.Value = i \'当前值为已经完成的行数 ElseIf i=drs.Count-1 \'当i为最大值减1时 p.Value = drs.Count \'当前值直接等于最大值 Forms("进度条独立窗口").Close End If If drs(i)("卷号").Contains(drs(i-1)("卷号")) Then drs(i-1)("库存标记") = False Else drs(i-1)("库存标记") = True End If Next drs(drs.Count-1)("库存标记") = True End If _dt工序合并表.SQLUpdate(drs) MessageBox.Show("完成全表库存标记计算!耗时: " & (Date.Now - t1).TotalSeconds & "秒,请不要频繁操作.", "提示",MessageBoxButtons.ok, MessageBoxIcon.Information) End If [此贴子已经被作者于2015/10/18 19:50:22编辑过]
|
-- 作者:大红袍 -- 发布时间:2015/10/19 9:51:00 -- 没执行一次sqlCompute,就连接一次数据库,自然慢。所以不要再for循环里面用sqlCompute。 |
-- 作者:huangfanzi -- 发布时间:2015/10/19 12:09:00 -- 明白老师的意思了,我想修改一下,我的想法是,既然不能在FOR里用sqlCompute,哪能不能在FOR外执行一次,将结果写进一个集体,然后在FOR里使用“记录标记2”的重量合计时,从这个集合中找,这样应该快,如果这样可行,能帮我写个“记录标记2”所对应的重量合计的集合代码吗? |
-- 作者:大红袍 -- 发布时间:2015/10/19 12:12:00 -- 一次性加载全部的 _dt工序合并表 后再用compute
|
-- 作者:huangfanzi -- 发布时间:2015/10/19 12:26:00 -- 何谓一次性全部加载,是以下的代码吗: Dim cmd_工序合并表 As New SQLCommand cmd_工序合并表.Connection Name = "ShcsErpSql" cmd_工序合并表.CommandText = "S elect * From {工序合并表}" _dt工序合并表 = cmd_工序合并表.ExecuteReader(True) 如果是上面的代码,我感觉好啰嗦,有一条代码实现上面的功能吗? 另外,如果我把工序合并表全总加载了,也就没必要用 SQLSelect,但不用这个SQLSelect,又如何保存数据呢,本来是用 _dt工序合并表.SQLUpdate(drs) 这个代码的,由于数据库已经在用了,现在不敢随便试了,老师能将我一楼的代码改下吗?
[此贴子已经被作者于2015/10/19 12:55:16编辑过]
|
-- 作者:jspta -- 发布时间:2015/10/19 13:05:00 -- 不会SQL的烦恼,学习下SQL,这种就很容易解决了 |
-- 作者:大红袍 -- 发布时间:2015/10/19 14:23:00 -- _dt工序合并表.LoadFilter = "" _dt工序合并表.Load
|