2012-07-03 91 views
5

以下代碼在i7- * 3.4 GHz windows-7 64位計算機上讀取25000行和5列的Excel表格需要2500毫秒。每個單元大約包含一個包含10個字符的字符串這是正常的嗎?我怎樣才能更快地閱讀它?OLEDB讀取Excel的性能

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); 
+2

數據集是「重」對象,更好地創建自己的類並使用datareader填充它的列表 – Boomer

+1

我認爲大多數性能成本是連接時間(嘗試修改記錄集大小以查看流逝時間是否顯着增加) – Pynner

+0

試試在連接完成後將StopWatch的開始移動到並查看方式這部分需要很多時間。但正如Boomer已經指出的那樣,嘗試使用OleDbCommand和OleDbDataReader而不是OleDbDataAdapter和DataSet,你也可能獲得相當的速度。 –

回答

6

我想提出我的發現作爲答案,因爲行爲總是一致的。

我已經複製了你的代碼,並把一個按鈕點擊事件,只是改變了一下,以確保配置適配器和每個測試的連接。

// 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); 
     } 
    } 

所以,這基本上就是你的代碼。該代碼在500ms內執行。但是.... 如果我在Excel 2010中保持文件test.xls打開,則執行時間跳至8000ms。

我自己也嘗試這種代碼的變化,但最終的結果是一樣的

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()

+0

我從來沒有想過原因是文件被打開。謝謝你的答案。 – hrzafer

+0

我注意到我從事的一個項目中的類似行爲,它從Excel讀取大量數據。我沒有做這種研究來縮小原因,因爲該項目並不需要任何性能(這是一個內部工具,仍然可以在一分鐘內完成處理)。我確實注意到,如果我打開了電子表格,似乎需要一分鐘時間才能完成電子表格未打開需要10秒的時間。我認爲這很奇怪,但這篇文章確認我並不瘋狂。 – Jim