SQL Server与.Net客户端 - 从服务器返回大量数据的最佳实践 - 性能改进

时间:2012-03-12 09:40:08

标签: asp.net .net sql sql-server performance

我正在攻击企业应用程序中的性能问题。我的一个SQL Proc返回超过2 MB的数据(XML纯文本)。用于执行该SP仅在DB服务器中占用大约600 ms。但是,它需要大约30秒才能在我的UI中获得响应。

SQL Server 2008 / .NET 4.0(IIS托管的Windows应用程序)

注意:在之前的性能迭代中 - 太多的数据库调用聚集在一起,因此可以调用许多数据库调用。但现在返回的数据非常庞大,面临着这个问题。

请帮助确定此处提供的任何标准或限制最佳做法,以提高效果。

基于以下收到的评论,想到这里添加: -

  1. 但是当我从本地SQLserver查询分析器执行与现场服务器连接相同的Sp调用时,我发现了这一点。它不是内联网,而是通过互联网在美国/印度之间进行通信。我也使用了dottrace工具和源代码进行了分析。这个数据没有瓶颈。在圈内有大约15个Db的呼叫(每个呼叫带有少量的Kbs),但是现在减少到俱乐部单个呼叫,但是以MB为单位携带大量数据。
  2. 此致 Karthikeyan.G

2 个答案:

答案 0 :(得分:0)

当然看起来像UI绑定。通过互联网2Mb不太可能需要30秒,但这可能取决于您的连接速度。

考虑到它只需要600毫秒来执行SP它有点长,所以最好是缓存它。无论如何,2MB的缓存并不多(只要不是每个用户)。

获取2MB数据,缓存它,拆分它。比如获取前100条记录,然后将这些行绑定到UI控件并实现分页。

然而,如果没有代码,我无法看到您绑定到什么类型的控件的数据的类型和深度。

答案 1 :(得分:0)

您可以使用异步编程:

    Dim connectionString As String = "server=.\SQLEXPRESS; database=master; Integrated Security=true; Asynchronous Processing=true"

  Private Sub btnDisplayCustomersCallback_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisplayCustomersCallBack.Click
        Dim sqlConnection As New SqlConnection(connectionString)
        Dim sqlCommand As SqlCommand = sqlConnection.CreateCommand()
        Dim asyncResult As IAsyncResult
        'Example of Asynchronous Callback Model

        sqlCommand.CommandText = "SELECT * FROM [customer]"
        sqlCommand.CommandType = CommandType.Text
        sqlConnection.Open()
        btnDisplayCustomersCallBack.Enabled = False


        Dim callback As AsyncCallback = New AsyncCallback(AddressOf DisplayCustomers)
        asyncResult = sqlCommand.BeginExecuteReader(callback, sqlCommand, CommandBehavior.CloseConnection)
    End Sub

  Private Sub DisplayCustomers(ByVal result As IAsyncResult)
        Dim dr As SqlDataReader
        Dim command As SqlCommand
        Dim del As DelFillGrid
        Try
            command = CType(result.AsyncState, SqlCommand)
            dr = command.EndExecuteReader(result)
            del = New DelFillGrid(AddressOf FillGrid)
            Threading.Thread.Sleep(5000)
            Me.Invoke(del, dr)

        Finally
            If (Not dr.IsClosed) Then
                dr.Close()
            End If
        End Try
    End Sub

Private Sub FillGrid(ByVal dr As SqlDataReader)
        Try
            Dim dt As New DataTable()
            dt.Load(dr)
            Me.DataGridView1.DataSource = dt
        Catch ex As Exception
            ' Because you're guaranteed this procedure 
            ' is running from within the form's thread, 
            ' it can directly interact with members of the form. 
        Finally
            btnDisplayCustomersCallBack.Enabled = True

            If dr IsNot Nothing Then
                dr.Close()
            End If

        End Try
    End Sub

在此,应用程序将在异步方法中生成ExecuteReader请求,并在获得结果时填充网格。直到该时间应用程序进行进一步处理。