Foxtable(狐表)用户栏目专家坐堂 → [求助]二段代码差不多,但一条执行效率非常低下,请老师看看。


  共有2731人关注过本帖树形打印复制链接

主题:[求助]二段代码差不多,但一条执行效率非常低下,请老师看看。

帅哥哟,离线,有人找我吗?
huangfanzi
  1楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:五尾狐 帖子:1104 积分:8956 威望:0 精华:0 注册:2014/10/25 11:24:00
[求助]二段代码差不多,但一条执行效率非常低下,请老师看看。  发帖心情 Post By: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编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
大红袍
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:贵宾 帖子:39310 积分:196782 威望:0 精华:1 注册:2015/4/25 9:23:00
  发帖心情 Post By:2015/10/19 9:51:00 [只看该作者]

没执行一次sqlCompute,就连接一次数据库,自然慢。所以不要再for循环里面用sqlCompute。

 回到顶部
帅哥哟,离线,有人找我吗?
huangfanzi
  3楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:五尾狐 帖子:1104 积分:8956 威望:0 精华:0 注册:2014/10/25 11:24:00
  发帖心情 Post By:2015/10/19 12:09:00 [只看该作者]

明白老师的意思了,我想修改一下,我的想法是,既然不能在FOR里用sqlCompute,哪能不能在FOR外执行一次,将结果写进一个集体,然后在FOR里使用“记录标记2”的重量合计时,从这个集合中找,这样应该快,如果这样可行,能帮我写个“记录标记2”所对应的重量合计的集合代码吗?

 回到顶部
帅哥哟,离线,有人找我吗?
大红袍
  4楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:贵宾 帖子:39310 积分:196782 威望:0 精华:1 注册:2015/4/25 9:23:00
  发帖心情 Post By:2015/10/19 12:12:00 [只看该作者]

一次性加载全部的 _dt工序合并表 后再用compute

 


 回到顶部
帅哥哟,离线,有人找我吗?
huangfanzi
  5楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:五尾狐 帖子:1104 积分:8956 威望:0 精华:0 注册:2014/10/25 11:24:00
  发帖心情 Post By: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
  6楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:七尾狐 帖子:1731 积分:11255 威望:0 精华:0 注册:2011/12/15 22:06:00
  发帖心情 Post By:2015/10/19 13:05:00 [只看该作者]

不会SQL的烦恼,学习下SQL,这种就很容易解决了

 回到顶部
帅哥哟,离线,有人找我吗?
大红袍
  7楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:贵宾 帖子:39310 积分:196782 威望:0 精华:1 注册:2015/4/25 9:23:00
  发帖心情 Post By:2015/10/19 14:23:00 [只看该作者]

_dt工序合并表.LoadFilter = ""

_dt工序合并表.Load

 


 回到顶部