2012-07-03 4 views
5

次のコードは、25000行と5列のExcelシートを読み取るために、i7- * 3.4GHz Windows-7 64ビットコンピュータで2500ミリ秒かかるとします。各セルには約10文字の文字列が含まれています。それは普通ですか?どうすればそれをもっと速く読むことができますか?Excelを読み取るOLEDBのパフォーマンス

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

データセットは "重い"オブジェクトで、独自のクラスを作成し、データウェアハウスを使用してそのリストを作成することをお勧めします – Boomer

+1

パフォーマンスのコストのほとんどは接続時間です(経過時間が劇的に増加するかどうかを確認するためにレコードセットサイズを変更してみてください) – Pynner

+0

接続が完了した後にStopWatchの開始点を移動し、その部分がかかる多くの時間。 Boomerが既に指摘したように、OleDbDataAdapterとDataSetの代わりにOleDbCommandとOleDbDataReaderを使ってみてください。 –

答えて

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オブジェクトのオープン()ではありません常にadapter.Fillある

()

+0

ファイルが開かれている理由は考えられませんでした。答えてくれてありがとう。 – hrzafer

+0

私はExcelから大量のデータを読み込むプロジェクトで同様の動作に気付きました。このプロジェクトでは、実際には何のパフォーマンスも必要としなかったため(これは、まだ1分以内に処理が完了する内部ツールです)、その原因を絞り込むための調査は行っていませんでした。私はスプレッドシートを開いていれば、スプレッドシートを開いていない状態で10秒かかるかもしれない場所を完了するまでに1分ほどかかるように見えたことは確かです。私はそれが奇妙だと思ったが、このポストの種類の私は狂っていないことを確認します。 – Jim

関連する問題