我的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 回答
感谢@BobRodes将我指向DataTable . 下面的代码使用DataTable改进了一个数据集上从18分钟到7秒的性能:)代码也简单得多 .
在DB和数据读取器之间的往返中,您可能会有很多额外的开销 . 您通过连接逐行整理数据,这通常是流程中最慢的部分 .
您最好使用DataSet,将所有记录拉入其中,然后迭代DataSet并构建阵列 . DataSet将位于本地存储中,因此访问速度应该更快 .
另一种方法是使用Access VBA构建所需的结果并将其存储在表中 . 然后,再次使用DataSet从Access中拉出整个表 . 如果您使用180,000条记录中的一小部分(我认为这不是这种情况),这将是更可取的,因为您不必在迭代它们之前将所有记录加载到DataSet中 .