c# - 为什么用第一个读者 read() 运行第二个读者比在它自己的读者阅读上运行它运行得更快?

标签 c# sql ms-access oledb

好吧,我目前正在运行这段代码,将大量数据从普适数据库移动到 Access 数据库

public List<HBPData> LoadData()
    {

        loadConnect(); //<-- get's the Pervasive/Access string from a text file
        List<HBPData> listofhbpdata1 = new List<HBPData>();
        List<HBPData> listofhbpdata2 = new List<HBPData>();

            PsqlConnection myConnection = new PsqlConnection();
            myConnection.ConnectionString = PervasiveString;
            myConnection.Open();
            PsqlCommand myCommand = new PsqlCommand("Select NUMBER, CUST_NAME, PO_NO, REQD_DATE, PO_NO, CUST_PO_NO, ORD_DATE, STATUS FROM SALES_ORDER_HEADER WHERE ORD_DATE > 20120220 Order By ORD_DATE desc", myConnection);
            PsqlDataReader myreader = null;
            myreader = myCommand.ExecuteReader();

            while (myreader.Read())
            {
                HBPData DataEntity = new HBPData();
                DataEntity.NUMBER = (myreader["NUMBER"].ToString());
                DataEntity.CUST_NO = (myreader["CUST_NAME"].ToString()).Replace("'","");
                DataEntity.PO_NO = (myreader["PO_NO"].ToString());
                DataEntity.RequiredDateTime = (myreader["REQD_DATE"].ToString());
                DataEntity.Tag = (myreader["PO_NO"].ToString());
                DataEntity.Shape = (myreader["CUST_PO_NO"].ToString());
                DataEntity.ExpectedCompletion = myreader["ORD_DATE"].ToString().Substring(0, 4) + "/" + myreader["ORD_DATE"].ToString().Substring(4, 2) + "/" + myreader["ORD_DATE"].ToString().Substring(6, 2);
                DataEntity.MostRecentStatus = (myreader["STATUS"].ToString());
                listofhbpdata1.Add(DataEntity);
            }

            PsqlCommand myCommand1 = new PsqlCommand("Select NUMBER, RECNO, CODE, ORDD_DESCRIPTION, BVORDQTY FROM SALES_ORDER_DETAIL WHERE BVRVADDDATE > 20120220 AND (PROD_CODE = \'MET\' OR PROD_CODE = \'MDT\') Order By NUMBER desc", myConnection);
            PsqlDataReader myreader1 = null;
            myreader1 = myCommand1.ExecuteReader();

            while (myreader.Read()) 
            {
                HBPData DataEntity = new HBPData();
                DataEntity.NUMBER = (myreader1["NUMBER"].ToString());
                DataEntity.RECNO = (myreader1["RECNO"].ToString());
                DataEntity.CODE = (myreader1["CODE"].ToString());
                DataEntity.DESCRIPTION = (myreader1["ORDD_DESCRIPTION"].ToString());
                DataEntity.Quantity = (myreader1["BVORDQTY"].ToString());
                listofhbpdata2.Add(DataEntity);
            }

            myConnection.Close();
            myreader1.Close();
            myreader.Close();






            System.Data.OleDb.OleDbConnection myAccessConnection = new System.Data.OleDb.OleDbConnection();

            myAccessConnection.ConnectionString = AccessString;
            myAccessConnection.Open();
            System.Data.OleDb.OleDbCommand myAccessCommand3 = new System.Data.OleDb.OleDbCommand("delete from AllOrders", myAccessConnection);
            myAccessCommand3.ExecuteNonQuery();

            for (int i = 0; i < listofhbpdata2.Count(); ++i)
            {
                System.Data.OleDb.OleDbCommand myAccessCommand2 = new System.Data.OleDb.OleDbCommand("" +
                    "Insert into AllOrders VALUES('" +
                      listofhbpdata2[i].NUMBER + "'" + ",'" + listofhbpdata2[i].RECNO.ToString() + "'" +
                    ",'" + listofhbpdata2[i].CODE + "','" + listofhbpdata2[i].DESCRIPTION.Replace("\'", "F") + "'" +
                    ",'" + listofhbpdata2[i].Quantity + "')", myAccessConnection);
                myAccessCommand2.ExecuteNonQuery();
            }

            myAccessConnection.Close();

        return listofhbpdata1;
    }

现在,。如果你仔细看,我打错了第二个读者,它应该读 while(myreader1.read()) ...我不小心把 myreader.read()

令我惊讶的是 myreader.read() 实际上运行成功了...... 这让我大吃一惊,... 我将其更改为“myreader1.read()” 而且代码的运行时间几乎翻倍......, 无论如何,检查数据库,所有数据都在那里.....

所以,根据常识,我想得很好,它可能每次运行第一个阅读器时都执行两组代码,

但是为什么所有数据都在那里?

Sales_Order_Header 中的字段明显少于 Sales_Order_Detail,如果它是第一个读取器,它不应该在表头表的末尾完成然后停止吗?那么为什么所有数据都在那里?

无论哪种方式,这段代码的运行时间都比较慢,有没有人对改进我的代码有什么建议?

编辑:只是为了表明第二位读者实际上并未返回 false: Debugger

如你所见,调试器已经进入了阅读器内部

最佳答案

您确定在第二次调用 myreader 时获得了正确的数据吗? 有些地方看起来不对劲:你循环遍历 myreader 应该从你的第一个 SELECT 语句中获取数据,但你的内部代码引用了 myreader1 .

所以这里的奇怪之处不是第二次迭代应该比第一次迭代快:而是第二次迭代返回了您期望的数据。
所以问题是:你确定在第二个循环中:

  • 您将从第二个 SELECT 语句中获得所有记录的预期迭代次数,例如 5000(与第一个语句中的记录数相反,例如 1000 ).

  • 您实际上是在第二个 SELECT 语句中获取每条记录的数据,而不仅仅是每次都获取相同的顶部记录。

关于问题的第二部分,如何提高数据传输速度,我建议如下:

  • 通过执行单个 INSERT 语句添加数据会很慢。
    看看这个问题,寻找一些非常快速的替代方案:
    Writing large number of records (bulk insert) to Access in .NET/C#

  • 如果您在 Access 数据库上做了大量工作,请保持连接永久打开,而不是打开/关闭它。为什么这会对性能产生重大影响,请参阅 Where is the OLE DB connection pooling? .
    我通常会创建一个名为 Dummy 的表,其中只有一条记录(不管它是什么),然后在该表上打开一个数据读取器,我一直打开它直到关闭应用程序.这确保数据库锁定文件保留在适当的位置,并且不会在我每次对数据库执行某些操作时创建/删除。如果您在数据库上执行大量操作,您会惊讶于这对性能的影响。

关于c# - 为什么用第一个读者 read() 运行第二个读者比在它自己的读者阅读上运行它运行得更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9874913/

相关文章:

SQL 列出 A 列出现多次但具有不同 B 列值的所有行

c# - 如何使 MdiChild 表单位于 C# 中的选项卡中?

c# - 在 Windows 8 桌面应用程序中获取位置

C# 通过 SOCKET 读取/写入 JAVA 并存在一些并发/套接字问题

sql - oracle的索引可以加注释吗?

C# Access Db 更新查询不起作用

C# WPF框架中的Page和MainWindow之间的数据交换

MySQL:无法在列中插入 '&'

sql - 如何使用 OpenRowSet 将数据插入到空白文件中?

c# - 为什么通过 OleDb 在 Access 数据库中调用我的更新查询不起作用?