Oracle 使用批量插入会显著降低处理速度吗?

Oracle 使用批量插入会显著降低处理速度吗?,oracle,oracle11g,Oracle,Oracle11g,我对Oracle相当陌生,但我已经在其他几个应用程序上使用了批量插入。大多数人似乎使用它速度更快,但我有一些人使用它会减慢应用程序的速度。这是我的第二次,它明显减慢了速度,所以我想知道我是否有一些设置不正确的地方,或者我需要以不同的方式设置它。在本例中,我有一个控制台应用程序,它处理约1900条记录。单独插入它们需要约2.5个小时,当我切换到批量插入时,需要5个小时 我根据这篇文章写的是 这就是我正在做的,我正在从数据库中检索一些记录,进行计算,然后将结果写入一个文本文件。计算完成后,我必须将这

我对Oracle相当陌生,但我已经在其他几个应用程序上使用了批量插入。大多数人似乎使用它速度更快,但我有一些人使用它会减慢应用程序的速度。这是我的第二次,它明显减慢了速度,所以我想知道我是否有一些设置不正确的地方,或者我需要以不同的方式设置它。在本例中,我有一个控制台应用程序,它处理约1900条记录。单独插入它们需要约2.5个小时,当我切换到批量插入时,需要5个小时

我根据这篇文章写的是

这就是我正在做的,我正在从数据库中检索一些记录,进行计算,然后将结果写入一个文本文件。计算完成后,我必须将这些结果写回数据库中的另一个表中,以便我们可以在需要时查看这些计算结果

当我进行计算时,我将结果添加到列表中。写完文件后,我会查看列表,如果有任何记录,我会进行批量插入

对于批量插入,我在App.config中设置了要插入的记录数。在这种情况下,我使用了250条记录。我认为最好将内存数组限制为250条记录,而不是1900条。我循环遍历该列表到App.config中的计数,并为每列创建一个数组。然后将这些数组作为参数传递给Oracle

App.config

<add key="UpdateBatchCount" value="250" />
数据管理器

public static void SaveEligibleHours(List<EligibleHours> listHours)
{            
    //set the number of records to update batch on from config file Subtract one because of 0 based index
    int batchCount = int.Parse(ConfigurationManager.AppSettings["UpdateBatchCount"]);


    //create the arrays to add values to
    string[] arrEmployeeId = new string[batchCount];
    decimal[] arrHours = new decimal[batchCount];
    string[] arrHoursSource = new string[batchCount];

    int i = 0;
    foreach (var item in listHours)
    {
        //Create an array of employee numbers that will be used for a batch update.
        //update after every X amount of records, update. Add 1 to i to compensated for 0 based indexing.
        if (i + 1 <= batchCount)
        {
            arrEmployeeId[i] = item.EmployeeID;
            arrHours[i] = item.Hours;
            arrHoursSource[i] = item.HoursSource;
            i++;
        }
        else
        {
            UpdateDbWithEligibleHours(arrEmployeeId, arrHours, arrHoursSource);

            //reset counter and array
            i = 0;
            arrEmployeeId = new string[batchCount];
            arrHours = new decimal[batchCount];
            arrHoursSource = new string[batchCount];
        }
    }

    //process last array
    if (arrEmployeeId.Length > 0)
    {
        UpdateDbWithEligibleHours(arrEmployeeId, arrHours, arrHoursSource);
    }

}


private static void UpdateDbWithEligibleHours(string[] arrEmployeeId, decimal[] arrHours, string[] arrHoursSource)
{
    StringBuilder sbQuery = new StringBuilder();
    sbQuery.Append("insert into ELIGIBLE_HOURS ");
    sbQuery.Append("(EMP_ID, HOURS_SOURCE, TOT_ELIG_HRS, REPORT_DATE) ");
    sbQuery.Append("values ");
    sbQuery.Append("(:1, :2, :3, SYSDATE) ");


    string connectionString = ConfigurationManager.ConnectionStrings["Server_Connection"].ToString();
    using (OracleConnection dbConn = new OracleConnection(connectionString))
    {
        dbConn.Open();

        //create Oracle parameters and pass arrays of data
        OracleParameter p_employee_id = new OracleParameter();
        p_employee_id.OracleDbType = OracleDbType.Char;
        p_employee_id.Value = arrEmployeeId;

        OracleParameter p_hoursSource = new OracleParameter();
        p_hoursSource.OracleDbType = OracleDbType.Char;
        p_hoursSource.Value = arrHoursSource;

        OracleParameter p_hours = new OracleParameter();
        p_hours.OracleDbType = OracleDbType.Decimal;
        p_hours.Value = arrHours;


        OracleCommand objCmd = dbConn.CreateCommand();
        objCmd.CommandText = sbQuery.ToString();
        objCmd.ArrayBindCount = arrEmployeeId.Length;
        objCmd.Parameters.Add(p_employee_id);
        objCmd.Parameters.Add(p_hoursSource);
        objCmd.Parameters.Add(p_hours);

        objCmd.ExecuteNonQuery();
    }
}
public static void saveligiblehours(列表小时数)
{            
//设置要从配置文件中更新批处理的记录数减去1,因为基于0的索引
int batchCount=int.Parse(ConfigurationManager.AppSettings[“UpdateBatchCount”]);
//创建要向其中添加值的数组
string[]ArEmployeeId=新字符串[batchCount];
小数点[]arrHours=新小数点[batchCount];
字符串[]arrHoursSource=新字符串[batchCount];
int i=0;
foreach(列表小时数中的var项目)
{
//创建将用于批量更新的员工编号数组。
//每X数量的记录更新一次后,更新。将1添加到i以补偿基于0的索引。
如果(i+10)
{
更新的bWithEligibleHours(arEmployeeId、arrhurs、arrhursSource);
}
}
私有静态void UpdateDbWithEligibleHours(字符串[]ArEmployeeId,十进制[]arrHours,字符串[]arrHoursSource)
{
StringBuilder sbQuery=新建StringBuilder();
sbQuery.Append(“插入符合条件的小时数”);
追加(((EMP_ID,HOURS_SOURCE,TOT_ELIG_HRS,REPORT_DATE));
sbQuery.Append(“值”);
追加((:1,:2,:3,SYSDATE)”;
string connectionString=ConfigurationManager.connectionString[“服务器连接”]。ToString();
使用(OracleConnection dbConn=新的OracleConnection(connectionString))
{
dbConn.Open();
//创建Oracle参数并传递数据数组
OracleParameter p_employee_id=新的OracleParameter();
p_employee_id.OracleDbType=OracleDbType.Char;
p_employee_id.Value=aremployeeid;
OracleParameter p_hoursSource=新的OracleParameter();
p_hoursSource.OracleDbType=OracleDbType.Char;
p_hoursSource.Value=arrhurssource;
OracleParameter p_hours=新的OracleParameter();
p_hours.OracleDbType=OracleDbType.Decimal;
p_hours.Value=arrhurs;
OracleCommand objCmd=dbConn.CreateCommand();
objCmd.CommandText=sbQuery.ToString();
objCmd.ArrayBindCount=aremployeeid.Length;
添加(p_employee_id);
添加(p_hoursSource);
objCmd.Parameters.Add(p_小时);
objCmd.ExecuteNonQuery();
}
}

你为什么要使用文件来完成这个过程?你甚至不需要代码,你可以在数据库内部创建一个存储过程来完成所有这一切。我打赌这将比你的方法快得多。我是根据你所写的内容来建议这一点的。在不知道要求的情况下,我可能是错的。而且1900条记录在pro方面也不算什么批处理。除非有多个表、外键、触发器和其他对象。我可能会查看存储过程,但我以前从未在Oracle中执行过,因此我必须查找一些示例。我来自MS SQL Server背景,在那里我一直使用存储过程,但我所在的公司似乎只使用内嵌过程QL。我一直在尝试使用实体框架,这是我用来单独插入记录的。语法有点不同,但从SQL Server到Oracle的结构是相同的。这个过程确实应该在数据库内部完成,而不需要任何外部语言。如果这个过程重复进行,你也可以创建一个作业,使其能够在配置的时间框架窗口内自行运行。您可以创建一个概念证明,向您的上司展示此过程会有多大改进。问题……我知道SP可能更适合此操作,但即使使用联机SQL,此操作也应能正常工作。有人看到我做得不正确或可能有问题吗e一种提高大容量插入性能的方法?你为什么要使用文件来完成此过程?你甚至不需要代码,你可以在数据库内部创建一个存储过程来完成所有这一切。我打赌这将比你的方法快得多。我建议基于你写的内容。在不知道要求的情况下,我可能会错。also 1900记录在批处理方面不算什么。除非有多个表、外键、触发器和其他对象。我可能会查看存储过程,但我以前从未在Oracle中执行过,因此我必须查找一些示例。我来自MS SQL Server背景,在那里我一直使用存储过程,但公司w在这里,我现在似乎只使用内嵌式SQL。我一直在尝试尽可能地使用实体框架,即
public static void SaveEligibleHours(List<EligibleHours> listHours)
{            
    //set the number of records to update batch on from config file Subtract one because of 0 based index
    int batchCount = int.Parse(ConfigurationManager.AppSettings["UpdateBatchCount"]);


    //create the arrays to add values to
    string[] arrEmployeeId = new string[batchCount];
    decimal[] arrHours = new decimal[batchCount];
    string[] arrHoursSource = new string[batchCount];

    int i = 0;
    foreach (var item in listHours)
    {
        //Create an array of employee numbers that will be used for a batch update.
        //update after every X amount of records, update. Add 1 to i to compensated for 0 based indexing.
        if (i + 1 <= batchCount)
        {
            arrEmployeeId[i] = item.EmployeeID;
            arrHours[i] = item.Hours;
            arrHoursSource[i] = item.HoursSource;
            i++;
        }
        else
        {
            UpdateDbWithEligibleHours(arrEmployeeId, arrHours, arrHoursSource);

            //reset counter and array
            i = 0;
            arrEmployeeId = new string[batchCount];
            arrHours = new decimal[batchCount];
            arrHoursSource = new string[batchCount];
        }
    }

    //process last array
    if (arrEmployeeId.Length > 0)
    {
        UpdateDbWithEligibleHours(arrEmployeeId, arrHours, arrHoursSource);
    }

}


private static void UpdateDbWithEligibleHours(string[] arrEmployeeId, decimal[] arrHours, string[] arrHoursSource)
{
    StringBuilder sbQuery = new StringBuilder();
    sbQuery.Append("insert into ELIGIBLE_HOURS ");
    sbQuery.Append("(EMP_ID, HOURS_SOURCE, TOT_ELIG_HRS, REPORT_DATE) ");
    sbQuery.Append("values ");
    sbQuery.Append("(:1, :2, :3, SYSDATE) ");


    string connectionString = ConfigurationManager.ConnectionStrings["Server_Connection"].ToString();
    using (OracleConnection dbConn = new OracleConnection(connectionString))
    {
        dbConn.Open();

        //create Oracle parameters and pass arrays of data
        OracleParameter p_employee_id = new OracleParameter();
        p_employee_id.OracleDbType = OracleDbType.Char;
        p_employee_id.Value = arrEmployeeId;

        OracleParameter p_hoursSource = new OracleParameter();
        p_hoursSource.OracleDbType = OracleDbType.Char;
        p_hoursSource.Value = arrHoursSource;

        OracleParameter p_hours = new OracleParameter();
        p_hours.OracleDbType = OracleDbType.Decimal;
        p_hours.Value = arrHours;


        OracleCommand objCmd = dbConn.CreateCommand();
        objCmd.CommandText = sbQuery.ToString();
        objCmd.ArrayBindCount = arrEmployeeId.Length;
        objCmd.Parameters.Add(p_employee_id);
        objCmd.Parameters.Add(p_hoursSource);
        objCmd.Parameters.Add(p_hours);

        objCmd.ExecuteNonQuery();
    }
}