Insert的效率问题,在线等!!!仅有90分了!!!

Lwg0901 2006-01-12 08:27:10
for i:=0 to 100000 do
begin
strSql := 'Insert Into XlsRW Values(''' + shtName + ''', ' + IntToStr(k) + ', ' + IntToStr(i) + ', ' + IntToStr(j) + ', ''' + s + ''');';
Qry.SQL.Add(strSql);
Qry.ExecSQL
end;


执行10万次以上的语句,要半个小时左右。如果提高效率?

改成下边的方式也一样:
for i:=0 to 100000 do
begin
strSql := 'Insert Into XlsRW Values(''' + shtName + ''', ' + IntToStr(k) + ', ' + IntToStr(i) + ', ' + IntToStr(j) + ', ''' + s + ''');';
Qry.SQL.Add(strSql);
end;
Qry.ExecSQL


请高人指点!!!


...全文
193 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
holyten 2006-01-13
  • 打赏
  • 举报
回复
如果是使用的是SQL SERVER的话,你可以调用DTS来完成你想要的功能,如果只是简单的逻辑增加的话,建议你在数据库创建一个存储过程来完成,但是效率仍然是不高的,当然最好的做法就是将东西放到数据库让他自己去做,你做的只是调用他们的春戳过程和函数就可以了。
asa516 2006-01-13
  • 打赏
  • 举报
回复
这是Delphy的问题,不是太清楚,帮你顶一下吧
FlyHope2005 2006-01-13
  • 打赏
  • 举报
回复
这样的操作最好用线程来解决;这样的话耗时肯定少
hellolongbin 2006-01-13
  • 打赏
  • 举报
回复
大批量数据,要从根源上解决的话,运行服务器端的存储过程,会比客户端-服务器端运行快很多
阿三 2006-01-13
  • 打赏
  • 举报
回复
你可以试试这样的方法:
adoconnection1.BeginTrans;
b := gettickcount();
try
for i := 1 to 100000 do
begin
with adoquery1 do
begin
close;
sql.Text := ' insert into test1(a,b,c,d) values(:a,:b,:c,:d)';
Parameters.ParamByName('a').Value := i;
Parameters.ParamByName('b').Value := inttostr(i)+'b';
Parameters.ParamByName('c').Value := inttostr(i)+'c';
Parameters.ParamByName('d').Value := inttostr(i)+'d';
execSql;
end;
self.Caption := inttostr(i);
application.ProcessMessages;
end;
adoconnection1.CommitTrans;
e := gettickcount();
showmessage('ok'+'用时'+inttostr(e-b));
except
adoconnection1.RollbackTrans;
end;


这样会比你那样写快一些,因为你那样写在数据库中每次执行都要重新编译你的语句,而采用参数形式会不需要重新编译了。
我在本地比较了一下10W条记行时间分别为:
299656,326750

如果你先把SQL存在一个stringlist中,然后执行速度会更快一些:200750
var
i,b,e: integer;
tlist: TStringList;
begin
adoconnection1.BeginTrans;
b := gettickcount();
tlist := TStringList.Create;
try
for i := 1 to 100000 do
begin
tlist.Add('insert into test1(a,b,c,d) values('+inttostr(i)+','''+inttostr(i)+'b'+''','''+inttostr(i)+'c'+''','''+inttostr(i)+'d'+''');');
self.Caption := inttostr(i);
application.ProcessMessages;
end;
with adoquery1 do
begin
close;
sql.Text := tlist.Text;
execSql;
end;
adoconnection1.CommitTrans;
e := gettickcount();
showmessage('ok'+'用时'+inttostr(e-b));
except
adoconnection1.RollbackTrans;
end;
end;


你也可以进行分段进行提交,比如1000条提交一次,会更好一些,没时间试了,你自己试一下





vivian12 2006-01-13
  • 打赏
  • 举报
回复
tstringlist是什么啊,那个执行很快吗?
Comer 2006-01-13
  • 打赏
  • 举报
回复
难道delphi解决不了这样的问题?

我知道PB、c#都可以解决的。。。


自己顶。。。郁闷ing...
zhangl_cn 2006-01-13
  • 打赏
  • 举报
回复
Qry.Prepare;
Qry.ExecSQL;


估计也快不了多少
Lwg0901 2006-01-13
  • 打赏
  • 举报
回复
我的数据是从客户端的excel文件中取到的,难道要执行10万次存储过程???

to xinshiji(自由我有)
触发器怎么用?我的每条记录之间并没有必然的联系阿?
太空11 2006-01-13
  • 打赏
  • 举报
回复
你试验一下存储过程 或者用触发器来完成 时间一定能减少一些 触发器应该是最快的
Lwg0901 2006-01-13
  • 打赏
  • 举报
回复
非常感谢阿日

用tstringlist确实快了很多,还没做10万数据级的测试,但是原先要三分半多的现在半分钟就搞定了

下周揭帖,继续看看有没有更好的方案!!!

向阿日学习,向阿日致敬

Lwg0901 2006-01-13
  • 打赏
  • 举报
回复
楼上几个大哥的意思是???

就是说效率只能相对的有一点提高,没办法提交很多了?

试试阿日的方法先
lovendII 2006-01-13
  • 打赏
  • 举报
回复
使用存储过程里面通过循环来完成,也许效率要提高得多,
写在客户端,如果数据量大,效率很低的。
Lwg0901 2006-01-12
  • 打赏
  • 举报
回复
如果使用ado.net的话,象这样的需求很容易解决的

难道ado下没有更好的方法了吗?
cuteant 2006-01-12
  • 打赏
  • 举报
回复
这个,,没有很好的办法吧。。数据总得一条一条的插入。
NightCloud 2006-01-12
  • 打赏
  • 举报
回复
像这样的需求,最好是在数据库服务器端用存储过程完成。在delphi里怎么做都会很慢的。
可以试试batchmove控件
Lwg0901 2006-01-12
  • 打赏
  • 举报
回复
更正:

方法2的效率要比方法1低

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧