【问题标题】:Performance: Speeding up application [closed]性能:加速应用程序[关闭]
【发布时间】:2014-01-20 03:44:14
【问题描述】:

附上,我已经编写了一些代码,进入我们的 SQL 数据库,执行一些查询,然后在 windows 窗体上应用 104 个标签的结果。

I have timed this procedure and it takes about 4 seconds which is way to long because my goal is to have this process done instantly so whenever a new employee is selected, his/her stats are loading as fast as possible.

我的问题:我可以做些什么来实现这个目标?

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

【问题讨论】:

  • -1。你输入一堆(可怕的)代码,并期望任何人(可能用水晶球)神奇地猜测问题出在哪里。您需要确定瓶颈,然后发布一个体面的问题。近距离投票。
  • 代码太多了。请大大减少这一点,以便轻松查看您执行的查询。
  • 您可以先在您的SqlCommand 中使用SqlParameters
  • @HighCore ,我是菜鸟,伙计。不过好吧,让我把这个问题重新表述一下。
  • 这个问题似乎是题外话,因为它是关于审查工作代码 - 试试codereview.stackexchange.com

标签: sql vb.net performance loops


【解决方案1】:

我看到至少三个明显的大问题,但由于我没有坐在你的办公桌前,所以无法确定哪个是罪魁祸首。

你的 SQL 太可怕了

看看这个查询中表查询的数量就知道了!

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 + 重绘

尽管上面的代码效率低下,但您调用它 52 次​​strong> 让情况变得更糟!我很惊讶这只需要 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)。如果这对您不起作用,您可能会发现这篇文章很有帮助:

How do I suspend painting for a control and its children?

【讨论】:

  • 感谢您的反馈!我几乎在学习。我只编程了大约 3 个月,还有很多东西要学。这个网站对我帮助很大,我几乎靠它生活。但是,一旦我犯了错误并有人指出,我一定不会再犯同样的错误,这反过来又提高了我的技能。
猜你喜欢
  • 1970-01-01
  • 2019-08-17
  • 2013-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-23
  • 1970-01-01
  • 2011-12-13
相关资源
最近更新 更多