求助!关于C#的Oracle 操作,效率低下
小弟最近在做一个日志分析的项目,就是把源数据拿出来处理一下在放回到一个新的表中。实际数据量大概在2亿条以上,目前的测试数据有700万左右。由于数据量过大,所以我没有一次性把数据都拿出来操作,而是用了一个Timer每次取一天的数据大概有200万左右来逐条处理。期间Timer停歇0.005秒。
但不知怎么回事处理效率越来越低,一开始的时候一秒大概能处理个10条左右的样子,可是程序运行一会以后,就变成了好几秒才能处理一条记录,并且速度越来越慢。
昨天进行了24小时的测试,结果才处理了20000多条数据,简直比人工处理还慢了。哪位大哥知道这是什么原因造成的?小弟从来没做过Oracle的操作,所以不知道问题出在哪了,Adapter 和Reader的方式我都试过了,结果都一样慢!!!
以下是Timer内的处理代码,请高手指点
try--------------------编程问答-------------------- 晕啊!!别沉了啊!!高手快来帮忙解答啊!!!!!!!!! --------------------编程问答-------------------- 晕啊!!别沉了啊!!高手快来帮忙解答啊!!!!!!!!! --------------------编程问答-------------------- 为什么用read()有连接处理 怎么不用无连接的Dataset,Datatable来处理数据量大的数据。 --------------------编程问答-------------------- 回3楼,一开始就是用DataSet 来做查询和插入操作的,但是效率很低,就考虑改用Reader的方式处理,结果一样效率还是很低 --------------------编程问答-------------------- 我觉得应该是表中数据过多造成的。
{
if ((DateTime.Now - beginDate).Minutes > 1)
{
System.Diagnostics.Process.GetCurrentProcess().MinWorkingSet = new System.IntPtr(5);
beginDate = DateTime.Now;
}
if (reader.Read())
{
i++;
string dnsname = reader.GetString(0);
decimal ipaddr = reader.GetDecimal(1);
int count = reader.GetInt32(2);
string SubDnsname = GetSubdomains(dnsname);
//string subdnsname = GetSubDomains(dnsname);
string ipchar = GetIPChar(ipaddr);
//RequestAdapter.Insert(dnsname, ipaddr, TempDate.Date, count, SubDnsname, 1, ipchar);
OracleParameter par1 = new OracleParameter("DNSNAME", OracleType.VarChar,256);
par1.Value = dnsname;
InsertCmd.Parameters.Add(par1);
OracleParameter par2 = new OracleParameter("IPADDR", OracleType.Number);
par2.Value = ipaddr;
InsertCmd.Parameters.Add(par2);
OracleParameter par3 = new OracleParameter("REQUESTDATE", OracleType.DateTime);
par3.Value = TempDate.Date;
InsertCmd.Parameters.Add(par3);
OracleParameter par4 = new OracleParameter("REQUESTCOUNT", OracleType.Number);
par4.Value = count;
InsertCmd.Parameters.Add(par4);
OracleParameter par5 = new OracleParameter("SUBDOMAINS", OracleType.VarChar,256);
par5.Value = SubDnsname;
InsertCmd.Parameters.Add(par5);
OracleParameter par6 = new OracleParameter("BATCH", OracleType.Number);
par6.Value = 1;
InsertCmd.Parameters.Add(par6);
InsertCmd.ExecuteNonQuery();
LogBox.AppendText(DateTime.Now.ToString() + "\t第 " + i + " 条记录处理完成\n");
LogBox.ScrollToEnd();
}
else
{
//修改数据库标志
string update = "UPDATE DNSLOG SET ISANALYSIS = 'Y' where REQUESTTIME>= to_date('" + TempDate.ToShortDateString() + "','yyyy/mm/dd') AND REQUESTTIME < to_date('" + date.ToShortDateString() + "','yyyy/mm/dd')";
cmd.CommandText = update;
cmd.ExecuteNonQuery();
reader.Close();
conn.Close();
reader.Dispose();
TempDate = date;
System.Diagnostics.Process.GetCurrentProcess().MinWorkingSet = new System.IntPtr(5);
//写入日志
LogBox.AppendText(DateTime.Now.ToString() + "\t" + TempDate.ToShortDateString() + "日志导入完成\n");
if (TempDate.Date > EndDate.Date)
{
LogBox.AppendText(DateTime.Now.ToString() + "\t日志分析结束.\n");
string log = "=================导入日志==================\n";
log += "开始时间:\t" + StartDate.ToString() + "\n";
log += "结束时间:\t" + DateTime.Now.ToString();
TimeSpan span = DateTime.Now - StartDate;
log += "用时:\t" + span.Hours + "小时" + span.Minutes + "分钟" + span.Seconds + "秒\n";
log += "共导入日志:\t" + i + "条\n";
log += "============================================\n";
FileClass.SaveLog(log);
ImportTimer.IsEnabled = false;
return;
}
else
{
GetReader();
}
}
}
catch(Exception ex)
{
LogBox.AppendText(DateTime.Now.ToString()+"\ta导入失败,异常信息"+ex.Message+"\n");
LogBox.ScrollToEnd();
}
楼主可以分析一下你的 INSERT 和 UPDATE 语句的执行性能。 --------------------编程问答-------------------- DataTable SQL语句优化 可以考虑从时间复杂度考虑 --------------------编程问答-------------------- 正确的处理方法:
写一个存储过程,在存储过程里面处理你的数据,放到一个新的表中,然后每天计划任务跑一下你的存储过程。 --------------------编程问答-------------------- 设几个关键点,打印一下系统时间,确定一下,主要费时的操作是集中在读库,还是写库上。看了一下你的代码,其中有关连接的代码,如果你的代码没有长时间中止数据为操作,不建议频繁开关连接,因为GC机制这样做做可能造成你的连接池溢出等待,打开一个连接,一直使用它,如果下次操作时间不可预期或在很长时间以后才关闭它。 --------------------编程问答-------------------- 此外要是插入的时候费时的话,你看可不可以用事务显示的做提交。反正我有时候对.net的autocommit机制没什么信心。
补充:.NET技术 , C#