简体   繁体   中英

SqlDataReader vs SqlDataAdapter: which one has the better performance for returning a DataTable?

I want to know which one has the better performance for returning a DataTable . Here for SqlDataReader I use DataTable.Load(dr)

Using SqlDataReader :

public static DataTable populateUsingDataReader(string myQuery)
{
    DataTable dt = new DataTable();
    using (SqlConnection con = new SqlConnection(constring))
    {
        SqlCommand cmd = new SqlCommand(myQuery, con);
        con.Open();
        SqlDataReader dr = null;
        dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
        if (dr.HasRows)
        {
            dt.Load(dr);
        }
        return dt;
    }
}

using SqlDataAdapter :

public DataTable populateUsingDataAdapter(string myQuery)
{
    SqlDataAdapter dap = new SqlDataAdapter(myQuery,cn);
    DataSet ds = new DataSet();
    dap.Fill(ds);
    return ds.Tables[0];
}

The difference will be negligible, so it's probably better to use the more concise version: SqlDataAdapter.Fill .

SqlDataReader.Fill creates an internal class LoadAdapter (derived from DataAdapter ) internally, and calls its Fill method: performance will be very similar to SqlDataAdapter.Fill(DataTable) .

There will be some small differences in initialization / validation of arguments, but as the number of rows increases, this will become less and less significant.

Note also that your second sample should be modified to be comparable with the first:

public DataTable populateUsingDataAdapter(string myQuery)
{
    using (SqlConnection con = new SqlConnection(constring))
    {
        SqlDataAdapter dap = new SqlDataAdapter(myQuery,con);
        DataTable dt = new DataTable();
        dap.Fill(dt);
        return dt;
    }
}

This question , and more specifically, this answer suggests that your second example is faster. It is certainly not an exhaustive benchmark but it is an interesting test.

Reflecting the source code of DataTable shows that calling DataTable.Load() actually creates an internal DataAdapter subclass called LoadAdapter and calls the Fill() method of DataAdapter . SqlDataAdapter does the bulk of its loading work in the exact same place.

More importantly, I would tend to favor the second example for readability. Neither example compares to the fast access provided by direct use of the DataReader , so I would opt for the cleaner code.

SqlDataReader has historically been significantly faster than SqlDataAdapter . Improvements may have been made in .NET 4.5, but I doubt it has improved enough to outpace the performance of the DataReader.

SqlDataReader将比SQlDataAdapter更快,因为它在连接状态下工作,这意味着第一个结果一旦可用就会从查询中返回。

In addition to the selected solution, I would like to add that:

Using the DataReader, you don´t need to know which type of DbConnection you have.

All you need is an instance which implements IDbConnection, with that you can use "connection.CreateCommand" and then "dbCommand.ExecuteReader" and then dataTable.Load.

But when you use DataAdapter you will need to know which connection is used (ie oracle, sqlserver, etc.)

(It´s not relevant for the thread starter, but I landed here using g**gle while looking for this topic.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM