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

我有一个在网格上显示报告的页面。 网格使用绑定到返回数据的类的Object数据源。 该类本身使用标准SQL查询来返回记录数并绑定到数据视图。 我们遇到的问题是有时需要大约10分钟才能加载,我知道必须有更好的方法,但不能为我的生活找出什么。 希望从任何人那里得到一些关于如何优化性能的见解。 数据类如下所示:任何反馈将不胜感激。 律师认为,约有650名律师被绑定到2张表格:律师和地点表。 执行计数的观点也被绑定到2个表格:当前案例和以前的案例表格,总共返回大约125,000个案例。 缓存是不可能的,因为最终用户将能够提供任何开始和结束日期来生成报告。


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


阅读“SQL执行计划”,你可能想查看你的表索引。 这些事情很可能会产生最大的结果。 有关更多信息,请参阅此SQL Server优化MSDN文章。

我也注意到你的VB代码中你没有参数化你的SQL字符串。 在上述之后,您应该考虑这样做以获得额外的性能优势。

有关使用SQL参数的更多信息,请参阅:

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


尝试使用存储过程。 这将会在Sql Server中编译代码,并提前执行计划。 约翰

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

上一篇: nested select statements taking too long to load on SQL server

下一篇: c# closing sqlconnection and sqldatareader or not?