现在需要循环将5000多条记录插入到数据库的表中,一共三个字段,记录条数在5000左右..
点击按钮一次性插入.我现在做的只是在数据库中做好存储过程,然后在客户端调用。
存储过程名:sp_addItem ,  三个参数,最为插入字段的值客户端程序:
procedure TForm1.ADDitemRelationDesc(ANo,Aname,Astatus:String); //添加数据
var
    adoquery1:Tadoquery;
begin
    adoquery1:=Tadoquery.Create(nil);
    try
       if not applySolutionDM.ADOConnection1.Connected then
           applySolutionDM.ADOConnection1.Open;
       adoquery1.Connection:=ApplysolutionDM.ADOConnection1;
       With adoquery1 do
       begin
           close;
           sql.clear;
           sql.add('Execute sp_addItem :tmpNo,:tmpName,:tmpStatus');
           parameters.parambyname('tmpNo').Value:=ANo;
           parameters.ParamByName('tmpName').Value:=AName;
           parameters.ParamByName('TmpStatus').Value:=Astatus;
           execsql;
       end;
   finally
       adoquery1.Free;
   end;现在这样的方法,插入的话,大概需要20秒左右..
有没有更好的解决方法嘛? 在循环插入时候,调用如上的代码,不断的动态创建adoquery 有没什么影响?另外,小问一下 多线程能否用到当前的操作中 。谢谢!

解决方案 »

  1.   

    为什么不用 insert into 的形式
      

  2.   

    insert into ??我存储过程是用的 insert into语句插入的啊存储过程执行不是更快嘛?
      

  3.   

    使用存储过程是正确的选择
    不断的动态创建adoquery这个不好,对速度肯定有影响。只需创建一次就够了,然后循环执行存储过程即可可以使用多线程,尤其是在数据量很大或要求速度很快的情况下
      

  4.   

    这个速度跟存储过程没有关系……要理解什么是存储过程。循环成一条SQL语句,然后执行比多次执行效率要高。
      

  5.   

    存储过程反而会慢,因为存储过程是短连接,每次都要有建立连接-》执行-》断开连接的操作
    而这个连接过程比较消耗资源。
    另外,动态的创建组件也是比较消耗资源的。最好用原生ado,建立长连接,建立一次连接之后,组好50个左右的insert语句,一起执行,执行完不关闭连接,继续组insert语句
      

  6.   

    可以先插入数据,然后建立索引。
    这样能够有效的提高效率。动态创建adoquery就不要想了。直接使用SQL语句或者使用append的方式都可以。
    append最后也是转化为sql语句方式执行的。
      

  7.   

    动态创建adoquery有影响。
    多线程未必快,因为还要考虑数据库对数据的锁和解。
      

  8.   


    按你上面的意思是批理執行 AddItemRelationDesc  吧,為什麼指量傳入 ; Insert into  語句,不是更好點。
      

  9.   

    楼主为什么要循环插入5000条数据,这个感到很奇怪,虽然你存储过程用的insert into,但是你外部调用如果是一条条循环的话,也没什么效率可言呀,如果只是想把一张表的三个字段内容添加到另一张表的三个字段中,一句 insert into就足够了
      

  10.   

    循环5000次,就得创建adoQuery 5000次,
    这样做非常不好。
      

  11.   

    那两句要命的
    sql.clear;
    sql.add('Execute sp_addItem :tmpNo,:tmpName,:tmpStatus');
    一定要提到循环外面来! 这样可以从20秒减少到5秒左右. 或者更少.
      

  12.   

    create table #temppp(tmpNo int,tmpName varchar(10),TmpStatus char(1))declare @a int
    set @a=1
    while @a<=5000
    begin
       insert into #temppp(tmpNo,tmpName,TmpStatus) values('1000','今天','1')
       set @a=@a+1
    enddrop table #temppp
    我的机器用0.04秒,如果你的机器高级,执行速度更快
      

  13.   


    要从一个文本文件中或者excel读取5000条左右的记录,记录格式为:
    A字段,B字段,C字段 每条记录都是三个字段,以逗号分隔..
    现在是读取一条就往数据库对应的这个表里添加一条..所以就循环插入5000次
      

  14.   


    什么意思??目前是很蠢的方法..
    for i:=0 to 5000 do
      AddItemRelationDesc(A,B,C); 这样来执行的,5000次
      

  15.   


    那是因为每次循环插入的时候,字段值不一样啊,所以要用变量传入啊..原生的insert into 更好?
      

  16.   

    不是每个时候每一种情况下都是“使用存储过程更快”,存储过程的快速在于其可以对批处理命令进行预编译,从而使得批量的命令执行更加有效率,这个主要体现在计算过程,而对于简单的insert和select则不尽如此了。对于mssqlserver,可以使用批量的insert:var
      Insert_Lst: TstringList;
    begin
      Insert_Lst := TStringList.Create;
      try
        for I := 0 to Count - 1 do //最好每500~1000条做一批
          Insert_lst.Add('Insert into tablename (Field1,Field2...) Value(''+StringValue1+''','+IntValue ...')');
        Insert_Lst.LineBrek := ';';//对于低版本如果不支持LineBreak的可以在上面的行末尾增加一个分号来解决
        ADOCommand.CommandText := Insert_Lst.Text;
       ADOCommand.Execute;
      finally
        Insert_Lst.Free;
      end;
    end;一个以前写的示例:
      const   AnsiString   SplitEmpty="",Split=";";     
        
      DWORD   StartTime=GetTickCount();     
        
      int   Count,iCacheSize=1000;     
        
      TStringList   *CacheList=new   TStringList();     
      try     
      {     
        
            for(int   i=0;i<200000;i++)     
            {     
                  if(Count)     
                        CacheList->Add(";Insert   into   tablename   (field1,field2,field3[...,fieldn])   values(value1,value2,value3[...,valuen])");     
                  else     
                        CacheList->Add("Insert   into   tablename   (field1,field2,field3[...,fieldn])   values(value1,value2,value3[...,valuen])");     
        
                  Count++;     
        
                  if(Count==iCacheSize)     
                  {     
                        ADOCommand->CommandText=CacheList->Text;     
                        CacheList->Clear();     
                        Count=0;     
                        ADOCommand->Execute();     
                  }     
                    
            }     
        
            if(Count>0)     
            {     
                  ADOCommand->CommandText=CacheList->Text;     
                  ADOCommand->Execute();     
            }     
      }     
      __finally     
      {     
            CacheList->Free();     
      }     
        
      DWORD   EndTime=GetTickCount();     
        
      ShowMessage((int)(EndTime-StartTime));     
      

  17.   

    原贴:http://topic.csdn.net/t/20061127/11/5187634.html
      

  18.   

    1、添加数据的操作不要用函数,直接写在主程序中(函数调用、释放也需要时间,为了效率可以牺牲一点可读性)2、可以实际试验一下究竟是存储过程快,还是直接insert快3、若数据可以分类,建议存入不同的表中,同时对几个表执行操作,这样查询也快。4、可以考虑多线程,把数据分几段,每个线程执行一段数据的添加操作。