【问题标题】:DataTable.Load is slower than IDataAdapter.Fill? [duplicate]DataTable.Load 比 IDataAdapter.Fill 慢? [复制]
【发布时间】:2012-08-30 05:56:59
【问题描述】:

我正在使用以下代码(Variant DataReader):

public DataTable dtFromDataReader(list<String> lstStrings)
{

    OleDBConn_.Open();
    using (OleDbCommand cmd = new OleDbCommand())
    {

        DataTable dt = new DataTable();
        OleDbDataReader reader = null;
        cmd.Connection = OleDBConn_;
        cmd.CommandText = "SELECT * from TableX where SUID=?";

        foreach (String aString in lstStrings)
        {
            cmd.Parameters.AddWithValue("?", aNode.SUID);
            reader = cmd.ExecuteReader();

            if (reader != null)
                dt.Load(reader);
            cmd.Parameters.Clear();
        }
        return dt;
    }
}

并将其与(Variant DataAdapter)进行比较:

public DataTable dtFromDataAdapter(list<String> lstStrings)
{
    dt = new DataTable();

    foreach (string aString in lstStrings)
    {
        sOledb_statement = String.Concat("SELECT * FROM TableX where SUID='", aString, "'");
        OleDbDataAdapter oleDbAdapter;
        using (oleDbAdapter = new OleDbDataAdapter(sOledb_statement, OleDBConn_))
        {
            GetOleDbRows = oleDbAdapter.Fill(dt);
        }
    }
}

当我连接到离线数据库(微软访问)时,我的阅读时间是(约 1.5k 检索项目):

  • 数据读取器 420 毫秒
  • 数据适配器 5613 毫秒

从 oracle 服务器读取时(约 30k 检索项):

  • 数据读取器 323845 毫秒
  • 数据适配器 204153 毫秒 (多次测试,时间变化不大)

即使更改命令的顺序(dataadapter 在 datareader 之前)也没有太大变化(我认为可能有一些预缓存..)。

我认为DataTable.Load 应该比DataAdapter.Fill 快​​一些?

而且我仍然相信,即使我看到了结果,它应该会更快。我在哪里浪费时间? (没有未处理的异常..)

【问题讨论】:

  • 你在哪里做你的计时?其中一种方法中有连接 Open() 调用,另一种没有。这可能是差异的一部分。
  • 另外,一个例子使用了参数,而另一个没有。在一种情况下,您也只能读取一行,但 DataAdapter.Fill 会全部读取。
  • @blesh Adapter 在填充方法中处理连接的打开和关闭。
  • 有趣,我不知道。

标签: c# oledb datareader dataadapter


【解决方案1】:

与您的代码设置方式相比,您的比较并不是真正的 Adapter 与 DataReader。您实际上是在比较 Adapter.Fill 与 DataTable.Load 方法。

DataReader 通常会在每条记录的基础上更快,因为您将一次遍历一条记录,并且可以在您读取每条记录时做出相应的反应。

由于您在两个实例中都返回 DataTable,因此 Adapter.Fill 方法可能是最佳选择。它就是为此而设计的。

【讨论】:

  • 两者都在 DataAdapter 内部调用protected virtual int Fill(DataTable[] dataTables, IDataReader dataReader, int startRecord, int maxRecords)。我不确定这是不是答案。
  • (不过我也不确定这不是答案)
  • 既然你告诉我我在那里做了什么,我明白了我在那里做了什么。谢谢!
  • 我认为添加和删除参数会浪费时间不使用适配器选择语句中的参数。所以这个比较是不正确的,你也不必检查阅读器是否有数据
猜你喜欢
  • 1970-01-01
  • 2019-06-26
  • 2020-01-20
  • 1970-01-01
  • 2017-01-06
  • 1970-01-01
  • 2012-10-31
  • 1970-01-01
  • 2011-07-17
相关资源
最近更新 更多