以文本方式查看主题

-  Foxtable(狐表)  (http://www.foxtable.com/bbs/index.asp)
--  专家坐堂  (http://www.foxtable.com/bbs/list.asp?boardid=2)
----  [求助]代码怎么优化下,SQL中执行1秒完成,窗口中执行很慢  (http://www.foxtable.com/bbs/dispbbs.asp?boardid=2&id=151946)

--  作者:绿火柴
--  发布时间:2020/7/7 21:42:00
--  [求助]代码怎么优化下,SQL中执行1秒完成,窗口中执行很慢
代码可否优化,
SQL中执行1秒完成。
窗口中数据执行完再保存为3分多钟。
如果查询到的数据不写入到表中也要70多秒。
如果是每行都保存乌龟一行的慢。
可否直接保存在后台数据表中。

Dim st As Date = Date.Now
Dim tbd As DataTable = DataTables("单位成本")
Dim cmd As New SQLCommand
Dim dt As DataTable
tbd.StopRedraw()
cmd.C
cmd.CommandText = "S elect 成品代号,convert( Char(4),year(缴库日期)) + ltrim(convert( Char(2),month(缴库日期))) As 年月,round(sum(生产成本)/sum(数量),6) As 单位成本 " & _
"f rom 缴库明细 wh ere 缴库类型=\'1正常制令缴库\' and 剔除 is null and 缴库日期 > \'2016-12-31\' gr oup by 成品代号,year(缴库日期),month(缴库日期) " & _
"union all " & _
"S elect 成品代号,convert( Char(4),year(缴库日期)) As 年月,round(sum(生产成本)/sum(数量),6) As 单位成本 from 缴库明细  " & _
"wh ere 缴库类型=\'1正常制令缴库\' and 剔除 is null and 缴库日期 > \'2016-12-31\' group by 成品代号,year(缴库日期) "
dt = cmd.ExecuteReader
\'不足行时,表增加相应行----------------------------------------------------------↓
If dt.DataRows.Count > tbd.DataRows.Count Then
    tbd.AddNew(dt.DataRows.Count - tbd.DataRows.Count)
End If
\'清空表中数据-------------------------------------------------------------------↓
For Each dr As DataRow In tbd.DataRows
    For Each dc As DataCol In tbd.DataCols
        dr(dc.Name) = Nothing
    Next
Next
\'进度条相关设置-------------------------------------------------------------------↓
Dim p As WinForm.ProgressBar
p = e.Form.Controls("ProgressBar1")
p.Maximum = dt.DataRows.Count \'设置最大值
p.Minimum = 0 \'设置最小值
\'查询到的数据赋值----------------------------------------------------------------↓
For i As Integer = 0 To dt.DataRows.Count - 1
    Dim tbdr As DataRow = tbd.DataRows(i)
    Dim dtr As DataRow = dt.DataRows(i)
    For Each tbc As DataCol In tbd.DataCols
        tbdr(tbc.Name) = dtr(tbc.Name)
    Next
    \'tbdr.Save
    If i Mod 100 = 0 Then
        p.Value = i \'当前值为已经完成的行数
    End If
Next
\'设置数值列数字格式------------------------------------------------------------------↓
For Each tbc1 As DataCol In tbd.DataCols
    If tbc1.IsNumeric Then
        tbc1.SetFormat("0.0")
    End If
Next
\'-收尾设置-----------------------------------------------------------------------------↓
tbd.Save
Tables("单位成本").AutoSizeCols
p.Value = dt.DataRows.Count
tbd.ResumeRedraw
MessageBox.Show("耗时: " & (Date.Now - st).TotalSeconds & "秒") \'计算并显示执行代码所花费的秒数
[此贴子已经被作者于2020/7/7 21:43:22编辑过]

--  作者:有点蓝
--  发布时间:2020/7/7 21:58:00
--  
dt = cmd.ExecuteReader
tbd.removefor("")
\'进度条相关设置-------------------------------------------------------------------↓
Dim p As WinForm.ProgressBar
p = e.Form.Controls("ProgressBar1")
p.Maximum = dt.DataRows.Count \'设置最大值
p.Minimum = 0 \'设置最小值
\'查询到的数据赋值----------------------------------------------------------------
For each dr as datarow in dt.DataRows
    Dim tbdr As DataRow = tbd.addnew
    For Each tbc As DataCol In tbd.DataCols
        tbdr(tbc.Name) = dtr(tbc.Name)
    Next
    \'tbdr.Save
    If i Mod 100 = 0 Then
        p.Value = i \'当前值为已经完成的行数
    End If
Next
\'设置数值列数字格式-------------DataTables("单位成本")如果是主表,直接在列属性设置即可,完全没有必要使用代码设置-----------------------------------------------------↓
For Each tbc1 As DataCol In tbd.DataCols
    If tbc1.IsNumeric Then
        tbc1.SetFormat("0.0")
    End If
Next
……

--  作者:绿火柴
--  发布时间:2020/7/7 22:55:00
--  
速度还是跟不上。统计完有8万多行。
--  作者:有点蓝
--  发布时间:2020/7/7 22:59:00
--  
这个代码的计算速度不可能和SQL执行一样的。逐行填充,并且还加上进度。不加进度可以提高30%速度,但是逐行填充就没有办法了。反正都是清空在填充,还不如直接使用Fill,或者直接使用sql填充然后再加载
--  作者:绿火柴
--  发布时间:2020/7/7 23:29:00
--  
明细数据很多,我是想做成一个统计表,然后平时查询这个统计表就可以了。
现在统计下来,差不多3分钟。
后续,会每个月的数据追载上去的。

直接使用sql填充然后再加载,怎么处理。不删除之前的数据,要载上去。


--  作者:有点蓝
--  发布时间:2020/7/8 8:49:00
--  
百度一下“insert into select”的用法:https://www.baidu.com/baidu?word=insert+into+select

如果使用代码,可以考虑专门建个项目放到服务器运行,在半夜定时执行一些费时的统计操作,然后把统计结果保存下来。我认识的一个的经销商系统就是这样处理的,每天2点左右进行日结并上报数据。

--  作者:绿火柴
--  发布时间:2020/7/8 11:22:00
--  
数据的处理在SQL上,,狐表只是执行加载查询。
明白了,多谢。