附上,我已经写了一些代码进入我们的SQL DB,执行一些queires,然后在Windows窗体上应用104个标签的结果。
我已经计划了这个程序,这需要大约4秒才能实现,因为我的目标是立即完成此过程,因此每当选择新员工时,他/她的统计数据都会尽快加载。
我的问题:我可以做些什么来实现这个目标?
Dim RESULT1 As Decimal 'declare this as global
Dim RESULT2 As Decimal 'declare this as global
Private Sub Week(ByVal week As Integer)
Dim queryString As String = "SELECT " & _
"(SELECT CAST(SUM(TARGET_SECONDS) AS DECIMAL)/ CAST(SUM(ROUTE_SECONDS) AS DECIMAL) FROM dbo.APE_BUSDRIVER_MAIN WITH(NOLOCK) WHERE WEEK_TIME = " & week & " AND APE_AREA_OBJID = " & lblAreaOBJID.Text & " AND EMPLOYEE_NAME = '" & cbEmployeeName.Text & "' AND YEAR_TIME = '" & cbYear.Text & "' AND ACTIVE = 1) AS RESULT1," & _
" (SELECT (SELECT CAST(COUNT(APE_BUSDRIVER_STATUS_OBJID) AS DECIMAL) FROM dbo.APE_BUSDRIVER_MAIN AS RESULT2 WHERE WEEK_TIME = " & week & " AND APE_AREA_OBJID = " & lblAreaOBJID.Text & " AND EMPLOYEE_NAME = '" & cbEmployeeName.Text & "' AND YEAR_TIME = '" & cbYear.Text & "' AND ACTIVE = 1 AND APE_BUSDRIVER_STATUS_OBJID = 1)/(SELECT CAST(COUNT(APE_BUSDRIVER_STATUS_OBJID) AS DECIMAL) FROM dbo.APE_BUSDRIVER_MAIN AS RESULT2 WHERE WEEK_TIME = " & week & " AND APE_AREA_OBJID = " & lblAreaOBJID.Text & " AND EMPLOYEE_NAME = '" & cbEmployeeName.Text & "' AND YEAR_TIME = '" & cbYear.Text & "' AND ACTIVE = 1)) AS RESULT2" & _
" FROM dbo.APE_BUSDRIVER_MAIN "
Using connection As New SqlConnection(SQLConnectionStr)
Dim command As New SqlCommand(queryString, connection)
connection.Open()
Dim reader As SqlDataReader = command.ExecuteReader()
' Call Read before accessing data.
If reader.HasRows Then
While reader.Read()
RESULT1 = reader("RESULT1")
RESULT2 = reader("RESULT2")
End While
Else
RESULT1 = 0
RESULT2 = 0
End If
' Call Close when done reading.
reader.Close()
End Using
End Sub
Private Sub LoadWeeklyStats()
For i As Integer = 0 To 51
Week(i + 1)
Dim LabelWkEff As String = "LblWkEff" + (i + 1).ToString
Dim myArray1 As Array = Controls.Find(LabelWkEff, False)
Dim myControl1 As Label = myArray1(0)
myControl1.Text = RESULT1
Dim LabelDeliveryStat As String = "lblDeliveryStat" + (i + 1).ToString
Dim myArray2 As Array = Controls.Find(LabelDeliveryStat, False)
Dim myControl2 As Label = myArray2(0)
myControl2.Text = RESULT2
Next
End Sub
答案 0 :(得分:3)
我发现至少有三个明显的问题,但是不可能说出哪个是罪魁祸首,因为我不是坐在你的办公桌前。
只需查看此查询中的表查询数量即可!
SELECT
(
SELECT
CAST(SUM(TARGET_SECONDS) AS DECIMAL) / CAST(SUM(ROUTE_SECONDS) AS DECIMAL)
FROM
dbo.APE_BUSDRIVER_MAIN WITH(NOLOCK)
WHERE
WEEK_TIME = @week
AND APE_AREA_OBJID = @areaOBJID
AND EMPLOYEE_NAME = @EmployeeName
AND YEAR_TIME = @Year
AND ACTIVE = 1
) AS RESULT1
, (
SELECT
(
SELECT
CAST(COUNT(APE_BUSDRIVER_STATUS_OBJID) AS DECIMAL)
FROM
dbo.APE_BUSDRIVER_MAIN AS RESULT2
WHERE
WEEK_TIME = @week
AND APE_AREA_OBJID = @AreaOBJID
AND EMPLOYEE_NAME = @EmployeeName
AND YEAR_TIME = @Year
AND ACTIVE = 1
AND APE_BUSDRIVER_STATUS_OBJID = 1
) / (
SELECT
CAST(COUNT(APE_BUSDRIVER_STATUS_OBJID) AS DECIMAL)
FROM
dbo.APE_BUSDRIVER_MAIN AS RESULT2
WHERE
WEEK_TIME = @week
AND APE_AREA_OBJID = @AreaOBJID
AND EMPLOYEE_NAME = @EmployeeName
AND YEAR_TIME = @Year
AND ACTIVE = 1
)
) AS RESULT2
FROM dbo.APE_BUSDRIVER_MAIN
我甚至无法开始为你重构这个因为问题的严重性而且我不知道你的架构,但我不得不猜测这是主要的罪魁祸首之一。如果可能的话,缓存在一个表中的部分或全部(如果性能确实是您的主要目标)。
您要返回多少行?如果你只需要一行,为什么还有多行呢?这种循环是完全没必要的,可能会为你杀死一些性能:
If reader.HasRows Then
While reader.Read()
RESULT1 = reader("RESULT1")
RESULT2 = reader("RESULT2")
End While
Else
RESULT1 = 0
RESULT2 = 0
End If
与上面的代码一样无效,你通过称之为 52次使情况变得更糟!我很惊讶这只需要4秒钟。
For i As Integer = 0 To 51
Week(i + 1)
Dim LabelWkEff As String = "LblWkEff" + (i + 1).ToString
Dim myArray1 As Array = Controls.Find(LabelWkEff, False)
Dim myControl1 As Label = myArray1(0)
myControl1.Text = RESULT1
Dim LabelDeliveryStat As String = "lblDeliveryStat" + (i + 1).ToString
Dim myArray2 As Array = Controls.Find(LabelDeliveryStat, False)
Dim myControl2 As Label = myArray2(0)
myControl2.Text = RESULT2
Next
除了无效的函数调用之外,您还要强制表单重新绘制104次(一次用于myControl1.Text
,另一次用于myControl2.Text
)。某些WinForm控件(面板等)具有您可以设置或调用的属性或方法,以允许您在末尾加载单个重绘的控件(例如SuspendLayout)。如果这对您不起作用,您可能会发现这篇文章很有帮助: