DataAdapter.填充速度很慢。如何用DataReader制作类似的东西?

问题描述 投票:0回答:1

我有一个带有 SQLDataAdapter 的实用程序类来读取数据。问题是,当我尝试使用 DataAdapter.fill 从 SP 返回数据时,执行填充操作并返回数据几乎需要大约 1 分钟 16 秒。(在 SSMS 中执行 SP 并返回 6 需要 5-6 秒数据集总计 <5000 records, total of all 6 datasets) Why is this difference happening?

public DataSet ExecuteQuery(string connName, string sp, List<SqlParameter> params)
{
    DataSet ds = new DataSet();
    using (SqlConnection cn = GetConnection(connName))
    {
        using (SqlCommand cmd = cn.CreateCommand())
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = sp;
            cmd.CommandTimeout = 600;
            // assign parameters passed in to the command
            
            foreach (var param in params)
            {
                cmd.Parameters.Add(param);
            }
            using (SqlDataAdapter da = new SqlDataAdapter(cmd))
            {
                da.Fill(ds);
            }
        }
    }
    return ds;
}

由于这是一个常见的函数,我想使用 SQLDataReader 创建新函数,该函数使用 .Load,但即使这样也很慢(实际上感觉比 DataAdapter 更慢)。 我必须在 10-15 秒内给出结果,那么我该如何解决这个问题?

c# sqldatareader sqldataadapter
1个回答
0
投票

DataReader 应该稍微快一点,但不明显。 5000条记录不算少,但也不算太多,应该可以。

我怀疑这很慢还有另一个原因,第一个嫌疑人是 SQL 查询。即使 7 秒也很多了。但是当您测试时,您是在服务器本身还是从远程进行测试?也许数据传输本身非常慢。这也不是一个很常见的问题。您可能还想检查连接字符串以了解连接方式。

无论如何,要运行数据读取器,您需要这样的东西:

   private static SqlDataReader ExecuteReader(SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, SqlConnectionOwnership connectionOwnership)
    {
        //create a command and prepare it for execution
        SqlCommand cmd = new SqlCommand();
        cmd.CommandTimeout = connection.ConnectionTimeout;  //leo - so setting the connecting timeout is all that we need.
        PrepareCommand(cmd, connection, transaction, commandType, commandText, commandParameters);
    
        //create a reader
        SqlDataReader dr;
    
        // call ExecuteReader with the appropriate CommandBehavior
        if (connectionOwnership == SqlConnectionOwnership.External)
        {
            dr = cmd.ExecuteReader();
        }
        else
        {
            dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
        }
    
        // detach the SqlParameters from the command object, so they can be used again.
        cmd.Parameters.Clear();
    
        return dr;
    }


private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters)
{
    //if the provided connection is not open, we will open it
    if (connection.State != ConnectionState.Open)
    {
        connection.Open();
    }

    //associate the connection with the command
    command.Connection = connection;

    //set the command text (stored procedure name or SQL statement)
    command.CommandText = commandText;

    //if we were provided a transaction, assign it.
    if (transaction != null)
    {
        command.Transaction = transaction;
    }

    //set the command type
    command.CommandType = commandType;

    //attach the command parameters if they are provided
    if (commandParameters != null)
    {
        AttachParameters(command, commandParameters);
    }

    return;
}

现在您知道要寻找什么,可能会找到更简单的示例。 一些重要的注意事项:

  1. 命令超时不包括连接超时。第一个达到限制的将引发错误。这就是为什么我将它们设置为相同的原因。
  2. 对数据读取器使用Using(),如果你让它保持打开状态,它实际上会保持打开状态,你将耗尽连接。
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.