Sql 总线驱动程序分析应用程序:加速查询、循环和正确语法
我在做一个叫做“公交车司机”的项目。公交车司机是一个物料处理员,他在生产车间的9条不同的装配线,捡起成品(翻新的接收器),然后把它们放在运输带上,然后在那里收缩包装并运到托盘上 我正在开发的应用程序每次跟踪他完成一个完整的路由,然后将他的统计数据存储在SQL数据库中 记录路线统计数据的应用程序运行良好,但我有另一个应用程序,名为“公交车司机分析器”。该应用程序获取所有公交车司机的数据,并生成4个图表Sql 总线驱动程序分析应用程序:加速查询、循环和正确语法,sql,vb.net,performance,loops,Sql,Vb.net,Performance,Loops,我在做一个叫做“公交车司机”的项目。公交车司机是一个物料处理员,他在生产车间的9条不同的装配线,捡起成品(翻新的接收器),然后把它们放在运输带上,然后在那里收缩包装并运到托盘上 我正在开发的应用程序每次跟踪他完成一个完整的路由,然后将他的统计数据存储在SQL数据库中 记录路线统计数据的应用程序运行良好,但我有另一个应用程序,名为“公交车司机分析器”。该应用程序获取所有公交车司机的数据,并生成4个图表 图1:路线效率(图中X值显示52周) 图2:准时交货率(本图X值显示52周) 图3:直方图(年初
Dim RESULT2为十进制“将其声明为全局”
Private Sub-LoadWeeklyStats()
是我用来保存结果并将其放置在windows窗体上的“LblWkEffXX”和“lblDeliveryStatXX”标签上的工具
每次选择一个新用户进行reviewal时,这个过程需要5秒钟,我知道这与SQL查询和for循环有关,但我不知道如何编写代码以更高效地获得我想要的结果
任何关于如何重写代码或我可以执行哪些其他选项以更快地实现相同结果的反馈都将不胜感激
如果您需要更多信息,请告诉我。绘图软件,如dundas,我相信即使是内置的绘图类型,通常也会包含多维值数组:一个值是X轴值,一个值是Y轴值。您不需要单独设置每个标签 但是,如果您想查看在当前系统中您的效率损失在哪里,我想指出:
Dim myArray1 As Array = Controls.Find(LabelWkEff, False)
Dim myControl1 As Label = myArray1(0)
myControl1.Text = RESULT1
及
这将告诉你这5秒是来自DB查询还是来自控件的数量。查找你正在进行的调用。你也可以分析你的代码,但这是一个非常简单的测试。如果速度显著加快,那么这是你的控件。查找而不是你的查询。如果,howev呃,它仍然很慢,然后是时候分析一下您的查询,看看是否需要重组或索引
如果速度更快,最好在第一次加载时创建一个控件数组,然后在后续填充中使用该数组。无需每次都找到控件,它们不会改变
类似于此工作流:
- 在类中创建两个新的
列表(标签)
成员变量——一个用于存储LabelWkEff
值,另一个用于存储LabelDeliveryStat
值
- 在表单加载时,循环:
For i As Integer=0到51,执行与前面相同的代码来查找控件
- 将它们添加到各自的新成员变量中,而不是设置它们的标签值
- 在您粘贴的代码中,在找到控件之前,使用
i
索引从新成员变量访问正确的控件,例如Dim myControl1 as Label=LabelWkEffs(i)
假设您的瓶颈是控件,那么这应该会使速度大大加快。粗略地看一下,我认为您尝试的操作没有本质上的错误。我认为最大的问题是打开52个sql连接,这是一个相对昂贵的过程。
因此,我建议最简单的节省效率的方法是修改查询以一次获取所有数据,或者简单地将连接实例传递到Week()方法。Joseph,正如许多人提到的,52次数据库往返不是一个好主意。
以下是我试图做到的:
创建一个存储过程,该过程接受参数并立即获取给定驱动程序52周的统计数据
在两周之间创建过程GetDriversStats(
)
作为
开始
declare @driver_stats table(weektime int, result1 decimal(38, 10), result2 decimal(38, 10))
declare @currentWeek int
set @currentWeek = @start_Week
while (@currentWeek <= @end_Week)
begin
insert into @driver_stats(weektime, result1, result2)
select
week_time
,(cast(sum(TARGET_SECONDS) AS DECIMAL)
/cast(sum(ROUTE_SECONDS) AS DECIMAL)) as Result1
,(cast(sum((case when APE_BUSDRIVER_STATUS_OBJID = 1 then 1 else 0 end)) as decimal)
/cast(sum((case when APE_BUSDRIVER_STATUS_OBJID <> 1 then 1 else 0 end)))) as Result2
FROM
dbo.APE_BUSDRIVER_MAIN a
WHERE
WEEK_TIME = @currentWeek AND APE_AREA_OBJID = @area_objid
AND EMPLOYEE_NAME = @emp_name and YEAR_TIME = @year_time AND ACTIVE = 1
group by week_time
set @currentWeek = @currentWeek + 1
end
select weektime, result1, result2 from @driver_stats
End Class
公共类MyDataLayer
公共共享函数GetWeeklyDriverStats(StartWeek整数,\u
EndWeek整数,YearTime整数_
AreaObjId整数,EmployeeName字符串)
结束功能
End Class
显然,对LoadWeeklyStats()没有太多的更改,只是将查询循环替换为通过数据模型对象列表的循环
Private Sub-LoadWeeklyStats()
Dim weeklyStats As List(ClassDriversStatistics的列表)=_
GetWeeklyDriverStats(1,52,cbYear.Text_
lblAreaOBJID.Text,cbEmployeeName.Text)
在周报表中,每个周报表作为字符串
Dim LabelWkEff As String = "LblWkEff" + weekStat.Week.ToString
Dim myArray1 As Array = Controls.Find(LabelWkEff, False)
Dim myControl1 As Label = myArray1(0)
myControl1.Text = weekStat.Result1
Dim LabelDeliveryStat As String = "lblDeliveryStat" + weekStat.Week.ToString
Dim myArray2 As Array = Controls.Find(LabelDeliveryStat, False)
Dim myControl2 As Label = myArray2(0)
myControl2.Text = weekStat.Result2
Next
End Sub
请
@area_objid int,
@emp_name varchar(255),
@year_time int,
@start_Week int = 1,
@end_Week int = 52
declare @driver_stats table(weektime int, result1 decimal(38, 10), result2 decimal(38, 10))
declare @currentWeek int
set @currentWeek = @start_Week
while (@currentWeek <= @end_Week)
begin
insert into @driver_stats(weektime, result1, result2)
select
week_time
,(cast(sum(TARGET_SECONDS) AS DECIMAL)
/cast(sum(ROUTE_SECONDS) AS DECIMAL)) as Result1
,(cast(sum((case when APE_BUSDRIVER_STATUS_OBJID = 1 then 1 else 0 end)) as decimal)
/cast(sum((case when APE_BUSDRIVER_STATUS_OBJID <> 1 then 1 else 0 end)))) as Result2
FROM
dbo.APE_BUSDRIVER_MAIN a
WHERE
WEEK_TIME = @currentWeek AND APE_AREA_OBJID = @area_objid
AND EMPLOYEE_NAME = @emp_name and YEAR_TIME = @year_time AND ACTIVE = 1
group by week_time
set @currentWeek = @currentWeek + 1
end
select weektime, result1, result2 from @driver_stats
Property Week As Integer = 0
Property Result1 As Decimal = 0.0 ' rename this property to something like RouteEffeciency
Property Result2 As Decimal = 0.0 ' rename this property to the appropriate name
Public Sub New()
End Sub
as List(Of ClassDriverStatistics)
Dim oDriverWeeklyStatsList As New List(Of ClassDriverStatistics)
Using connection As New SqlConnection(SQLConnectionStr)
Dim command As SqlCommand = New SqlCommand("GetDriverStatsBetweenWeeks", connection)
connection.CommandType = CommandType.StoredProcedure
connection.Open()
Dim reader As SqlDataReader = command.ExecuteReader()
Do While objReader.Read()
Dim rec As ClassDriverStatistics = New ClassDriverStatistics()
rec.Week = Convert.ToInt32(theObjReader("weektime"))
rec.Result1 = Convert.ToDecimal(theObjReader("result1"))
rec.Result2 = Convert.ToDecimal(theObjReader("result2"))
oDriverWeeklyStatsList.Add(rec)
Loop
objReader.Close()
End Using
Return oDriverWeeklyStatsList
Dim LabelWkEff As String = "LblWkEff" + weekStat.Week.ToString
Dim myArray1 As Array = Controls.Find(LabelWkEff, False)
Dim myControl1 As Label = myArray1(0)
myControl1.Text = weekStat.Result1
Dim LabelDeliveryStat As String = "lblDeliveryStat" + weekStat.Week.ToString
Dim myArray2 As Array = Controls.Find(LabelDeliveryStat, False)
Dim myControl2 As Label = myArray2(0)
myControl2.Text = weekStat.Result2