【问题标题】:Performance of OLEDB to read ExcelOLEDB 读取 Excel 的性能
【发布时间】:2012-07-03 23:42:59
【问题描述】:

在 i7-*3.4 GHz windows-7 64 位计算机上,以下代码需要大约 2500 毫秒才能读取 25000 行和 5 列的 Excel 工作表。每个单元格大约包含一个 10 个字符的字符串。正常吗?我怎样才能更快地阅读它?

 Stopwatch sw1 = Stopwatch.StartNew();
 var connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; " +
                                             "Extended Properties=Excel 12.0;", filename);

 var adapter = new OleDbDataAdapter("SELECT * FROM [roots$]", connectionString);
 var ds = new DataSet();
 adapter.Fill(ds, "roots");
 sw1.Stop(); Console.WriteLine("Time taken for excel roots: {0} ms", sw1.Elapsed.TotalMilliseconds);

【问题讨论】:

  • 数据集是“重”对象,最好创建自己的类并使用 datareader 填充它的列表
  • 我认为大部分性能成本是连接时间(尝试修改记录集大小以查看经过的时间是否急剧增加)
  • 尝试将秒表的起点移到建立连接后,看看该部分需要多少时间。但正如 Boomer 已经指出的那样,尝试使用 OleDbCommand 和 OleDbDataReader 而不是 OleDbDataAdapter 和 DataSet,您可能还会获得相当快的速度。

标签: c# performance excel oledb


【解决方案1】:

我希望将我的发现作为答案提出,因为行为始终是一致的。

我已经复制了您的代码并将其放入按钮单击事件中,只是稍作更改以确保为每个测试处理适配器和连接。

// test.xls contains 26664 rows by 5 columns. Average 10 char for column, file size is 2448kb
// OS Windows 7 Ultimate 64 bit. CPU Intel Core2 Quad Q9550 2.83ghz 
// 8gb ram and disk C is an 256gb SSD cruzer

    private void button1_Click(object sender, EventArgs e)
    {

        string filename = "c:\\tmp\\test.xls";
        Stopwatch sw1 = Stopwatch.StartNew(); 
        var connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; " + 
                                              "Extended Properties=Excel 12.0", filename);

        using(var adapter = new OleDbDataAdapter("SELECT * FROM [roots$]", connectionString))
        {
            var ds = new DataSet();
            adapter.Fill(ds, "roots");
            sw1.Stop();
            Console.WriteLine("Time taken for excel roots: {0} ms", sw1.Elapsed.TotalMilliseconds);
        }
    }

所以,这基本上就是您的代码。此代码在 500 毫秒内执行。但.... 如果我在 Excel 2010 中打开 test.xls 文件,执行时间会跳到 8000 毫秒。

我也尝试过这种代码变体,但最终结果是一样的

    private void button1_Click(object sender, EventArgs e)
    {
        string filename = "c:\\tmp\\test.xls";
        Stopwatch sw1 = Stopwatch.StartNew(); 
        var connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}; " + 
                                              "Extended Properties=Excel 12.0", filename);
        using(OleDbConnection cn = new OleDbConnection(connectionString))
        {
            cn.Open();
            using(var adapter = new OleDbDataAdapter("SELECT * FROM [roots$]", cn))
            {
                var ds = new DataSet();
                adapter.Fill(ds, "roots");
                sw1.Stop();
                Console.WriteLine("Time taken for excel roots: {0} ms", sw1.Elapsed.TotalMilliseconds);
            }
        }
    }

而且,不,它不是 OleDbConnection 的 Open(),始终是 adapter.Fill()

【讨论】:

  • 我从没想过原因是文件被打开了。谢谢你的回答。
  • 我在一个从 Excel 读取大量数据的项目中发现了类似的行为。我没有进行那种研究来缩小原因,因为该项目实际上并不需要任何性能(它是一个内部工具,仍然可以在一分钟内完成处理)。我确实注意到,如果我打开电子表格,似乎需要一分钟才能完成,而电子表格未打开可能需要 10 秒。我觉得这很奇怪,但这篇文章证实了我没有疯。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多