Загрузка больших файлов Visual FoxPro очень медленная.C # (OleDB) - PullRequest
0 голосов
/ 31 августа 2011

Я хочу загрузить большие файлы .DBF (Visual FoxPro) в DataTable. Для файлов меньшего размера <300 МБ он отлично работает с командой fill и работает довольно быстро. Но для больших файлов у меня не хватает памяти, и мне нужно загрузить их на более мелкие части. (Загрузка строки 0 ... 1000, затем 1001..2000 и т. Д.) </p>

Исходя из некоторого кода, найденного в интернете, я выполнил эту операцию, input start - строка, с которой нужно начать чтение, а max - количество строк, которые я хочу прочитать.

Проблема в том, что даже если я просто хочу прочитать 5 строк, это занимает около 30-60 секунд на моей машине из-за очень медленного выполнения Command.ExecuteReader.

  public DataTable LoadTable2(string folder, string table, int start, int max)
  {
        string ConnectionString = "Provider=vfpoledb.1;Data Source="+folder+"\\"+table;
        OleDbConnection Connection = new OleDbConnection(ConnectionString);
        Connection.Open();
        string dataString = String.Format("Select * from {0}", table);
        OleDbCommand Command = new OleDbCommand(dataString, Connection);
        //Takes very long time on large files.
        OleDbDataReader Reader = Command.ExecuteReader(CommandBehavior.SequentialAccess);
        DataSet ds = new DataSet();
        var dt = ds.Tables.Add(table);
        // Add the table columns. 
        for (int i = 0; i < Reader.FieldCount; i++)
        {
           dt.Columns.Add(Reader.GetName(i), Reader.GetFieldType(i));
        }
        int intIdx = 0;
        int cnt = 0;
        while (Reader.Read())
        {
           if (intIdx >= start)
           {
              DataRow r = dt.NewRow();
              // Assign DataReader values to DataRow.  
              for (int i = 0; i < Reader.FieldCount; i++)
                 r[i] = Reader[i];
              dt.Rows.Add(r);
              cnt++;
           }
           if (cnt >= max)
           {
              break;
           }
           intIdx++;
        }
        Reader.Close();
        Connection.Close();
        return dt;
  }

Я тестировал как OLE, так и ODBC соединение, без большой разницы. Все файлы находятся на локальном диске.

У кого-нибудь есть хорошая идея, как сделать это намного быстрее?

С наилучшими пожеланиями Андерс

1 Ответ

1 голос
/ 31 августа 2011

Я считаю, что с этим драйвером (VFPOLEDB) вы можете изменить свой запрос, указав интересующие номера записи.Таким образом, не нужно будет читать кучу записей, чтобы добраться до отправной точки.Тогда не было бы необходимости пропускать какие-либо записи;просто прочитайте весь запрошенный набор результатов.Запрос может выглядеть так:

SELECT * from thetable where recno() >= 5000 and recno() <= 5500

Я понял, что у меня установлен этот драйвер, и только сейчас проверил его, и он работает.Однако я не думаю, что это «оптимизирует» это утверждение.Теоретически, он может напрямую вычислять смещения записей, используя номера записей, но (основываясь на простом наблюдении за запросом на большем dbf), кажется, что выполняется полное сканирование таблицы.Однако с FoxPro вы можете создать индекс на recno(), и тогда он будет оптимизирован.

...