0

レポートをグリッドに表示するページがあります。グリッドは、データを返すクラスにバインドされたオブジェクト データ ソースを使用します。クラス自体は、標準の SQL クエリを使用してレコード数を返し、データビューにバインドします。私たちが抱えている問題は、ロードに約10分かかることがあり、もっと良い方法が必要であることはわかっていますが、私の人生ではできません。これをパフォーマンスのために最適化する方法について、誰かから洞察を得たいと思っています。データ クラスを以下に示します。フィードバックをお寄せください。2 つのテーブル (弁護士と場所のテーブル) にバインドされている弁護士ビューによって返される約 650 の弁護士があります。カウントが実行されるビューも、現在のケースと以前のケースのテーブルの 2 つのテーブルにバインドされており、合計で約 125,000 件のケースが返されます。

Dim PendingStringBuilder As String = "((dbo.cases.attorney_id = dbo.attorneys.att_id) AND (dbo.cases.date_assigned <= @StartDate) AND (dbo.cases.closing_date >= @StartDate OR dbo.cases.closing_date IS NULL)) OR ((dbo.casepreviousattorneys.attorney_id =
 dbo.attorneys.att_id) AND (dbo.casepreviousattorneys.previous_assignment_date <= @StartDate) AND (dbo.casepreviousattorneys.unassignment_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 <= @EndDate)) OR ((dbo.casepreviousattorneys.attorney_id = dbo.attorneys.att_id) AND (dbo.casepreviousattorneys.previous_assignment_date
 >= @StartDate) AND (dbo.casepreviousattorneys.previous_assignment_date <= @EndDate))"

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
4

2 に答える 2

1

「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

于 2012-04-12T22:53:44.570 に答える
-1

ストアド プロシージャを使用してみてください。これにより、コードが SQL Server で既にコンパイルされ、実行計画が事前に保存されます。ジョン

于 2015-03-30T16:58:49.890 に答える