nested select statements taking too long to load on SQL server

I have a page that displays reports on a grid. The grid uses an Object data source which is bound to a class that returns data. The class itself uses standard SQL query to return a count of records and binds to a dataview. The issue we are having is that it takes about 10 minutes sometimes to load and I know there has to be a better way but cannot for the life of me, figure out what. Hoping to get some insights from anyone on how to optimize this for performance. The data class is shown below: any feedback would be appreciated. There are about 650 attorneys returned by the attorney view which is bound to 2 tables: attorneys and locations table. The view on which the counts are performed on is bound to 2 tables also: current cases and previous cases tables and that returns about 125,000 cases total. Caching is out of the question because the end user will be able to supply any start and end dates to generate the report.


Dim PendingStringBuilder As String = "((dbo.cases.attorney_id = dbo.attorneys.att_id) AND (dbo.cases.date_assigned = @StartDate OR dbo.cases.closing_date IS NULL)) OR ((dbo.casepreviousattorneys.attorney_id =
 dbo.attorneys.att_id) AND (dbo.casepreviousattorneys.previous_assignment_date = @StartDate OR dbo.casepreviousattorneys.unassignment_date IS NULL))"


Dim AssignedStringBuilder As String = "((dbo.cases.attorney_id = dbo.attorneys.att_id) AND (dbo.cases.date_assigned >= @StartDate) AND (dbo.cases.date_assigned = @StartDate) AND (dbo.casepreviousattorneys.previous_assignment_date 

Dim CountTable As String = " dbo.cases WITH (NOLOCK) INNER JOIN dbo.tlkpcasetype ON dbo.cases.case_type_id = dbo.tlkpcasetype.case_type_id FULL OUTER JOIN dbo.casepreviousattorneys ON dbo.cases.case_no = dbo.casepreviousattorneys.case_no"




 Dim dt As New DataTable("ReportTable")
        Dim dr As DataRow

        dt.Columns.Add("CasesPending", Type.[GetType]("System.Int32"))
        dt.Columns.Add("CasesAssigned", Type.[GetType]("System.Int32"))

        dt.Columns.Add("ProbationViolation", Type.[GetType]("System.Int32"))
        dt.Columns.Add("BailOnly", Type.[GetType]("System.Int32"))

        dt.Columns.Add("TotalCases", Type.[GetType]("System.Int32"))

        dt.Columns.Add("AttorneyID", Type.[GetType]("System.Int32"))
        dt.Columns.Add("AttorneyName", Type.[GetType]("System.String"))
        dt.Columns.Add("AttorneyFirstName", Type.[GetType]("System.String"))
        dt.Columns.Add("AttorneyLastName", Type.[GetType]("System.String"))

        dt.Columns.Add("UnitID", Type.[GetType]("System.Int32"))
        dt.Columns.Add("UnitName", Type.[GetType]("System.String"))
        dt.Columns.Add("UnitType", Type.[GetType]("System.String"))

        dt.Columns.Add("OfficeID", Type.[GetType]("System.Int32"))
        dt.Columns.Add("Office", Type.[GetType]("System.String"))


        If cn.State = ConnectionState.Closed Then cn.Open()

        Dim cmd As SqlCommand
        Dim rdr As SqlDataReader



        strSQL = "SELECT DISTINCT dbo.attorneys.user_id, dbo.attorneys.att_id AS AttorneyID, dbo.attorneys.first_name +' '+ dbo.attorneys.last_name AS AttorneyName, dbo.attorneys.unit_id AS UnitID, dbo.tlkpunit.unit AS UnitName, dbo.tlkpunit.unit_type AS UnitType,
 dbo.tlkpunit.office_id AS OfficeID, dbo.tlkpoffice.office AS Office, "


        strSQL += "(SELECT COUNT(DISTINCT dbo.cases.case_no) AS ExprCasesPending FROM " & CountTable & " WHERE (" & PendingStringBuilder & ")) As CasesPending, "


        strSQL += "(SELECT COUNT(DISTINCT dbo.cases.case_no) AS ExprCasesAssigned FROM " & CountTable & " WHERE (dbo.tlkpcasetype.case_type  'Probation Violation') AND (dbo.tlkpcasetype.case_type  'Bail Only') AND (" & AssignedStringBuilder & ")) As CasesAssigned,
 "


        strSQL += "(SELECT COUNT(DISTINCT dbo.cases.case_no) AS ExprProbationViolation FROM " & CountTable & " WHERE (dbo.tlkpcasetype.case_type = 'Probation Violation') AND (" & AssignedStringBuilder & ")) As ProbationViolation, "


        strSQL += "(SELECT COUNT(DISTINCT dbo.cases.case_no) AS ExprBailOnly FROM " & CountTable & " WHERE (dbo.tlkpcasetype.case_type = 'Bail Only') AND (" & AssignedStringBuilder & ")) As BailOnly, "


        strSQL += "(SELECT COUNT(DISTINCT dbo.cases.case_no) AS ExprTotalCases FROM " & CountTable & " WHERE (" & AssignedStringBuilder & ")) As TotalCases "


        strSQL += " FROM dbo.attorneys WITH (NOLOCK) LEFT OUTER JOIN dbo.tlkpunit ON dbo.attorneys.unit_id = dbo.tlkpunit.unit_id LEFT OUTER JOIN dbo.tlkpdivision ON dbo.tlkpunit.division_id = dbo.tlkpdivision.division_id LEFT OUTER JOIN dbo.tlkpoffice ON dbo.tlkpunit.office_id
 = dbo.tlkpoffice.office_id WHERE (dbo.tlkpunit.unit  'test-unit') "



        cmd = New SqlCommand(strSQL, cn)

        cmd.Parameters.AddWithValue("@StartDate", DateAStart)
        cmd.Parameters.AddWithValue("@EndDate", DateAEnd)

        rdr = cmd.ExecuteReader()





        While rdr.Read

            If rdr("CasesPending").ToString = 0 And rdr("CasesAssigned") = 0 And rdr("ProbationViolation").ToString = 0 And rdr("BailOnly") = 0 Then

'Do not add record

            Else


                dr = dt.NewRow()

                dr("CasesPending") = CInt(rdr("CasesPending"))
                dr("CasesAssigned") = CInt(rdr("CasesAssigned"))

                dr("ProbationViolation") = CInt(rdr("ProbationViolation"))
                dr("BailOnly") = CInt(rdr("BailOnly"))

                dr("TotalCases") = CInt(rdr("TotalCases"))


                dr("AttorneyID") = rdr("AttorneyID")
                dr("AttorneyName") = rdr("AttorneyName")

                dr("UnitID") = rdr("UnitID")
                dr("UnitName") = rdr("UnitName")
                dr("UnitType") = rdr("UnitType")

                dr("OfficeID") = rdr("OfficeID")
                dr("Office") = rdr("Office")

                dt.Rows.Add(dr)

            End If





        End While

        rdr.Close()
        cmd.Dispose()

        If cn.State = ConnectionState.Open Then cn.Close()


        Dim dv As New DataView(dt)

        dv.Sort = "AttorneyName ASC"

        Return dv


Read up on "sql execution plans" and you may want to review your table indexes. It is likely that these things will yield the greatest results. See this SQL Server Optimization MSDN article for more information.

I also notice in your VB code you are not parameterizing your SQL string. You should consider doing this after the above for additional performance benefit.

For more information on using SQL parameters see:

http://www.codinghorror.com/blog/2005/04/give-me-parameterized-sql-or-give-me-death.html http://technet.microsoft.com/en-us/library/ms186219.aspx


Try using a stored procedure. This will have the code compiled in the Sql Server already and the execution plan stored ahead of time. John

链接地址: http://www.djcxy.com/p/44028.html

上一篇: System.Data.OleDb.OleDbException无效的参数

下一篇: 嵌套的select语句花费太长时间才能加载到SQL Server上