插入到Oracle c#

插入到Oracle c#,c#,oracle,C#,Oracle,我有一个C#应用程序,基本上可以为测试数据库生成大量数据。它正在使用Oracle.DataAccess版本4.112.3.0 出于某种奇怪的原因,大约每插入30ish,OracleCommand.ExecuteNonQuery()语句都会传递几秒钟。在某些情况下,我们正在通话15秒 当通过DSN使用通用ODBC连接时,我没有这个问题。。。。 我不能再使用DSN,因为我希望此应用程序即使在未安装oracle客户端的系统上也能工作 非常感谢您的帮助 我的连接类的代码,处理打开连接和执行插入设置以同时

我有一个C#应用程序,基本上可以为测试数据库生成大量数据。它正在使用Oracle.DataAccess版本4.112.3.0

出于某种奇怪的原因,大约每插入30ish,OracleCommand.ExecuteNonQuery()语句都会传递几秒钟。在某些情况下,我们正在通话15秒

当通过DSN使用通用ODBC连接时,我没有这个问题。。。。 我不能再使用DSN,因为我希望此应用程序即使在未安装oracle客户端的系统上也能工作

非常感谢您的帮助

我的连接类的代码,处理打开连接和执行插入设置以同时适用于SQLServer和Oracle

public Connection(string username,
            string password,
            string serverAddress,
            String servicename,
            string qual)
        {
            uid = username;
            pwd = password;
            server = serverAddress;
            oraServiceName = servicename;
            qualifier = qual;
            string oradb = "Data Source=(DESCRIPTION="
                             + "(ADDRESS=(PROTOCOL=TCP)(HOST=" + serverAddress + ")(PORT=1521))"
                             + "(CONNECT_DATA=(SERVICE_NAME="+servicename+")));"
                             + "User Id=" + username + ";Password=" + password + ";";
                oraConn = new OracleConnection(oradb);
                oraCom = new OracleCommand("",oraConn);
                oraCom.CommandType = System.Data.CommandType.Text;


        } 
public void doInsert(string s)
        {

            try
            {
                sqlCom.CommandText = s;
                sqlCom.Connection = sqlConn;
                sqlCom.ExecuteNonQuery();
            }
            catch (NullReferenceException e)
            {
                try
                {
                    oraCom.CommandText = s;
                   // oraCom.Connection = oraConn;

                    oraCom.ExecuteNonQuery();

                }
                catch (NullReferenceException e2)
                {
                    throw e2;
                }
            }

        }
实际执行插入操作的代码

public void generateData()
    {
        try
        {
            indivID = GenerateId();
            conn.openConn();
            conn.doInsert(tData.insertIndividual());
            //number of calls
            for (long x = 0; x < numCalls; x++)
            {
                countCalls++;
                callidkey = GenerateId();

                //start segments
                for (long y = 0; y < numSegments; y++)
                {
                    if (countSegs != numSegments)
                    {
                        countSegs++;
                    }
                    else
                    {
                        countSegs = 0;
                    }
                    INTX_ID = GenerateId();
                    conn.doInsert(this.tData.insertINTXSEGMENT());
                    //start parts and recordings
                    for (long n = 0; n < numParts; n++)
                    {

                       // INTX_PART_ID = GenerateId();
                        conn.doInsert(tData.insertINTXPART());
                        if (countParts != numParts)
                        {
                            countParts++;
                        }
                        else
                        {
                            countParts = 0;
                        }
                        if (genRec)
                        {

                            recData.recordingid = GenerateId();
                            conn.doInsert(recData.insertRecData());
                            conn.doInsert(recData.insertRecPart());
                            if (countRecs != numParts)
                            {
                                countRecs++;
                            }
                            else
                            {
                                countRecs = 0;
                            }
                        }
                    }
                }
            }
        }
        catch (Exception)
        {}
        }
    }
public void generateData()
{
尝试
{
individual=GenerateId();
conn.openConn();
conn.doInsert(tData.insertIndividual());
//通话次数
对于(长x=0;x
我不是程序员,只是个dba。 有几件事需要记住:

  • 尽可能重复使用打开的连接-连接管理需要很长时间
  • 为插入使用绑定变量,最好使用批量收集
  • 如果您实现了这两个简单规则,接下来要检查的是数据库联机重做日志文件的大小。默认值为512KB。如果它们已满,你的应用程序将冻结,直到下一个重做文件中有空间为止。重做以循环方式使用。填充后,如果数据库处于archivelog模式,则会将其复制到存档中。这可能会在执行许多插入时导致速度减慢

    检查数据库的日志模式:

    select log_mode from v$database;
    
    检查重做大小和组数:

    select group#, bytes, first_time from v$log;
    
    重做应该在非常快的存储上。它只是在做顺序io。 如果重做与正常负载相比较小,请增大其大小。(通常我们的目标是每15分钟有一个日志开关)如果您经常有更多,请增加大小。
    如果正常情况下,一个小时内大约有4个交换机,并且只有您的负载能很快填满它们,请添加日志组。

    谢谢您提供的信息,我会检查它们并更新您。您能想出基于dsn的连接不能做到这一点的任何原因吗?我也在重复使用相同的连接。Connection是一个打开连接的类,然后我向Connection.doinsert提供一个字符串,该字符串将处理插入操作。我不知道基于dsn的操作与您的不同。我不认识任何变量绑定操作。好的,我检查了,Logmode是NOARCHIVELOG-我确实更改了代码以进行显式提交,这有点帮助-我确实找到了几个60秒以上插入的实例,自从进行显式提交以来,我的插入时间最多为20秒。它仍然很长,因此任何输入都是值得赞赏的。重做的大小是多少?表上是否有约束和/或触发器和/或索引?过去24小时有3个日志。每只50毫克。这些表格都是相关的。表)INTXSegment表)INTX_Participant表)RECINTXPARTICIPANT表)RECORDINGDATA INTXSegment有一个PKey字符(22)(guid)INTX_Participant有一个PKey字符(22)(guid),FKey指向INTXSegment RECORDINGDATA有PKey字符(22)(guid)RECINTXPARTICIPANT有一个PKey字符(22)(guid),两个FKey一个指向INTX_Participant字符(22)还有一个是RecordingDataChar(22),你刚才说的绑定变量——你是说Oracle不必做任何修改吗?