首页 文章

如何改进我的C#代码以将数据从MS Access读入2d阵列?

提问于
浏览
0

我的C#代码可以工作,但是处理180,000行数据需要将近一个小时 . 我正在寻找提高性能的方法 . 在读取新数据时是否有更快或更好的方法来增加数组,或者SQL语句是否更有效?谢谢 .

int row = 0;
string[,] timeSeriesData = new string[row, colSize];
using (OleDbConnection AccessConn = new OleDbConnection(strAccessConn))
{
    OleDbCommand cmdGetData = AccessConn.CreateCommand();
    cmdGetData.CommandText = sqlSELECT;

    AccessConn.Open();
    OleDbDataReader thisReader = cmdGetData.ExecuteReader();
    while (thisReader.Read())
    {
        string[,] tempArray = new string[row + 1, colSize];
        Array.Copy(timeSeriesData, tempArray, timeSeriesData.Length);
        timeSeriesData = tempArray;

        timeSeriesData[row, 0] = thisReader.GetDateTime(0).ToOADate().ToString();
        for (int j = 1; j < colSize; j++)
        {
            if (thisReader.IsDBNull(j))     
            {
                timeSeriesData[row, j] = "-999";  
            }
            else
            {
                timeSeriesData[row, j] = Convert.ToString(thisReader[j]);
            }
         }
         row++;
    }
    thisReader.Close();
    AccessConn.Close();
}

我的SQL语句通常是这样的:

SELECT [TimeStamp], IIF([CH1Avg_Qual] IS NULL OR [CH1Avg_Qual]=0, [CH1Avg], NULL) AS Col1, 
IIF([CH2Avg_Qual] IS NULL OR [CH2Avg_Qual]=0, [CH2Avg], NULL) AS Col2, 
IIF([CH3Avg_Qual] IS NULL OR [CH3Avg_Qual]=0, [CH3Avg], NULL) AS Col3, 
IIF([CH7Avg_Qual] IS NULL OR [CH7Avg_Qual]=0, [CH7Avg], NULL) AS Col4, 
IIF([CH9Avg_Qual] IS NULL OR [CH9Avg_Qual]=0, [CH9Avg], NULL) AS Col5, 
IIF([CH10Avg_Qual] IS NULL OR [CH10Avg_Qual]=0, [CH10Avg], NULL) AS Col6, 
IIF([CH11Avg_Qual] IS NULL OR [CH11Avg_Qual]=0, [CH11Avg], NULL) AS Col7 
FROM [DataTable] ORDER BY [TimeStamp]

2 回答

  • 0

    感谢@BobRodes将我指向DataTable . 下面的代码使用DataTable改进了一个数据集上从18分钟到7秒的性能:)代码也简单得多 .

    DataTable timeSeriesDataDT = new DataTable();
    using (OleDbConnection AccessConnDT = new OleDbConnection(strAccessConn))
    {
        using (OleDbCommand cmdGetDT = new OleDbCommand(sqlSELECT, AccessConnDT))
        {
            AccessConnDT.Open();
            OleDbDataAdapter adapter = new OleDbDataAdapter(cmdGetDT);
            adapter.Fill(timeSeriesDataDT);
        }
    }
    
  • 0

    在DB和数据读取器之间的往返中,您可能会有很多额外的开销 . 您通过连接逐行整理数据,这通常是流程中最慢的部分 .

    您最好使用DataSet,将所有记录拉入其中,然后迭代DataSet并构建阵列 . DataSet将位于本地存储中,因此访问速度应该更快 .

    另一种方法是使用Access VBA构建所需的结果并将其存储在表中 . 然后,再次使用DataSet从Access中拉出整个表 . 如果您使用180,000条记录中的一小部分(我认为这不是这种情况),这将是更可取的,因为您不必在迭代它们之前将所有记录加载到DataSet中 .

相关问题