加载大型 Visual FoxPro 文件非常慢。 C#(OleDB)

发布于 2024-12-02 02:15:26 字数 1776 浏览 3 评论 0原文

我想将大型 .DBF (Visual FoxPro) 文件加载到数据表中。 对于较小的文件 < 300MB,它可以很好地使用填充命令,并且运行速度相当快。 但对于较大的文件,我的内存不足,需要将它们加载到较小的部分。 (加载行0...1000,然后1001..2000等等)

根据在互联网上找到的一些代码我做了这个操作,输入start是开始读取的行,max是我想要的行数阅读。

问题是,即使我只想读取 5 行,由于 Command.ExecuteReader 的执行速度非常慢,在我的机器上也需要大约 30-60 秒。

  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 连接,没有太大区别。 文件全部在本地磁盘上。

有谁知道如何使其更快?

此致 安德斯

I want to load large .DBF (Visual FoxPro) files into a DataTable.
For smaller files < 300MB it works fine with a fill command, and it runs pretty fast.
But for larger file I run out of memory and need to load them into smaller parts.
(Loading row 0...1000, then 1001..2000 and so on)

Based on some code found on the internet I made this operation, input start is the row to start reading from and max is the number of rows that I want to read.

The problem is that even if I just want to read 5 rows it takes around 30-60seconds on my machine due to the very slow execution of the 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;
  }

I have tested with both OLE and ODBC connection, no big difference.
Files are all on local disc.

Does anyone have a good idea for how to make this much faster?

Best regards
Anders

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

始终不够 2024-12-09 02:15:26

我相信使用该驱动程序(VFPOLEDB),您可以更改查询以指定感兴趣的记录号。这样就不需要阅读一堆记录才能到达起点。这样就没有必要跳过任何记录;只需读取整个请求的结果集。查询可能如下所示:

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

我意识到我已经安装了这个驱动程序,并且刚刚对其进行了测试,它确实可以工作。但是,我不认为它“优化”了该声明。理论上,它可以使用记录号直接计算记录偏移量,但是(基于对较大 dbf 查询的简单观察),它似乎进行了全表扫描。但是,使用 FoxPro,您可以在 recno() 上创建索引,然后对其进行优化。

I believe that with that driver (VFPOLEDB), you can change your query to specify the record numbers of interest. That way it would not be necessary to read through a bunch of records to get to the starting point. It would then not be necessary to skip over any records; just read the entire requested result set. The query might look like this:

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

I realized that I have this driver installed and just now tested it and it does work. However, I don't think it "optimizes" that statement. In theory, it could directly compute the record offsets using record numbers, but (based on simple observation of a query on a larger dbf), it seems to do a full table scan. However, with FoxPro, you could create an index on recno(), and then it would be optimized.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文