-3

Attached, I have written some code that goes into our SQL DB, performs some queires, and then applies the results for 104 labels, on the windows form.

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.

My question: What can I do differenlty to make this goal 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
JDB
  • 25,172
  • 5
  • 72
  • 123
Joseph.Scott.Garza
  • 133
  • 1
  • 2
  • 8
  • -1. You throw in a bunch of (horrible) code and expect anyone to magically (probably with a Crystal Ball) guess where the problem is. You need to identify the bottleneck and then post a decent question. Close-voting. – Federico Berasategui Jan 02 '14 at 16:32
  • Way too much code. Please strip this down considerably so that it is easy to see the queries you execute. – usr Jan 02 '14 at 16:32
  • 4
    You could start by using [SqlParameters](http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparameter(v=vs.110).aspx) in your `SqlCommand` – Bjørn-Roger Kringsjå Jan 02 '14 at 16:32
  • @HighCore , Im a rookie, man. but okay, let me rephrase the question better. – Joseph.Scott.Garza Jan 02 '14 at 16:33
  • @usr, Ok, I stripped it down. I still can't format the sql statements so they're easy to see. – Joseph.Scott.Garza Jan 02 '14 at 16:40
  • Like Bjørn-Roger said, you should SqlParameters. You have a big security issue right now. http://en.wikipedia.org/wiki/SQL_injection – the_lotus Jan 02 '14 at 16:50
  • Also, why are you looping all rows if you are just getting the last result? You should run your query and make sure it only return one result. – the_lotus Jan 02 '14 at 16:54
  • 1
    This question appears to be off-topic because it is about reviewing working code - try over at http://codereview.stackexchange.com/ – Bridge Jan 02 '14 at 17:27
  • @Bridge - I suppose it would depend on your definition of "working". – JDB Jan 02 '14 at 20:59

1 Answers1

3

I see at least three big glaring problems, though it's impossible to say which is the main culprit because I'm not sitting at your desk.

Your SQL is Horrendous

Just look at the number of table queries in this query!

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

I can't even begin to refactor this for you because of the enormity of the problem and I don't know your schema, but I'd have to guess that this is one of the primary culprits. If at all possible, cache some or all of this in a single table (if performance really is your primary goal).

Unnecessary looping

How many rows are you returning? And why are there multiple rows if you only need one? This looping is completely unnecessary and might be killing some performance for you:

    If reader.HasRows Then
        While reader.Read()
            RESULT1 = reader("RESULT1")
            RESULT2 = reader("RESULT2")
        End While
    Else
        RESULT1 = 0
        RESULT2 = 0
    End If

Inefficiency * 52 + Repaint

As ineffecient as the code above is, you've made it worse by calling it 52 times! I'm amazed this is only taking 4 seconds.

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

In addition to the ineffecient function call, you are forcing your form to repaint itself 104 times (once for myControl1.Text and again for myControl2.Text). Some WinForm controls (panels, etc) have a property or method you can set or call to allow you to load controls with a single repaint at the end (SuspendLayout for example). If that doesn't work for you, you may find this post helpful:

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

Community
  • 1
  • 1
JDB
  • 25,172
  • 5
  • 72
  • 123
  • Thanks for your feedback! I'm pretty much learning as go. I've only been programming for about 3 months and there is soo much to learn. This site has helped me sooo much and I pretty much live by it. However, once I make a mistake and someone points it out, Im sure to never make the same mistake again which in turn improves my skill. – Joseph.Scott.Garza Jan 02 '14 at 23:01