向各位高手请教:WebService 中数据入库效率很低,400 条记录竟然用到 2.343 秒, 求如何优化性能。

yyunffu 2008-06-18 04:06:59
cmd->Parameters->Add(L"@chkDesc",   SqlDbType::VarChar, 300);
cmd->Parameters->Add(L"@LetRoomID", SqlDbType::VarChar, 20);
cmd->Parameters->Add(L"@chkTypeID", SqlDbType::Int, 4);
cmd->Parameters->Add(L"@chkResult", SqlDbType::Int, 4);
cmd->Parameters->Add(L"@WorkerID", SqlDbType::VarChar, 20);
for each(DataRow^ dr in tbChk->Rows){
//DateTime ^dtNow3 = DateTime::Now;
if(dr->IsNull(dcLetChkDesc) || String::IsNullOrEmpty(dr[dcLetChkDesc]->ToString()->Trim()))
cmd->Parameters[0]->Value = DBNull::Value;
else
cmd->Parameters[0]->Value = dr[dcLetChkDesc]->ToString();

if(dr->IsNull(dcLetChkLetID) || String::IsNullOrEmpty(dr[dcLetChkLetID]->ToString()->Trim()))
cmd->Parameters[1]->Value = DBNull::Value;
else
cmd->Parameters[1]->Value = dr[dcLetChkLetID]->ToString();

if(dr->IsNull(dcLetChkTypeID))
cmd->Parameters[2]->Value = DBNull::Value;
else
cmd->Parameters[2]->Value = Convert::ToInt32(dr[dcLetChkTypeID]);

if(dr->IsNull(dcChkResult))
cmd->Parameters[3]->Value = DBNull::Value;
else
cmd->Parameters[3]->Value = Convert::ToInt32(dr[dcChkResult]);

cmd->Parameters[4]->Value = strWorkerID;

/*if(!m_dbAccess->RunProc(L"proc_sys_getLetChk", params1, sqlTran))
throw gcnew Exception();*/
cmd->ExecuteNonQuery();
}
...全文
134 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
yyunffu 2008-06-19
  • 打赏
  • 举报
回复
6楼 xxoo2007 高见。
的确是在并发测试中出现进程间数据库锁争用,导致出现如下错误:
proc_sys_getLet事务(进程 ID 70)与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务。

求高手指点!
xxoo2007 2008-06-19
  • 打赏
  • 举报
回复
1.判定记录是否存在的这句
if(not exists(select * from CheckItems where LetRoomID = @LetRoomID
and WorkerID = @WorkerID
and chkTypeID = @chkTypeID))
建议换成
select count(*)
count的效率是比较好的,如果CheckItems记录很多而且没有索引, 这个检查可呢会消耗掉不少的时间.

2.分成 存储过程, 后台代码,环境设置几部分,判定一下时间到底消耗在哪部分.

3.如果是并发状态下,入库的时间更长的话,需要考虑是否产生了数据库锁.

yyunffu 2008-06-19
  • 打赏
  • 举报
回复
问题不是在第一次初始化,那个我已经排除了。
我这里相当一个中间平台,作为后台管理及终端访问的中介,隔离终端与管理系统联系,以降低管理系统负担。
所以我这里是有独立数据库的,问题是出现在我这里入数据库中的。

可能构建类似:
exec proc_sys_getLetChk ...
.
.
.
这样的序列,类似批量执行会提高效率,我试一下。
badtank 2008-06-19
  • 打赏
  • 举报
回复
看描述结构是 移动设备<--->WebService<--->后台系统<--->数据库
这就需要逐一排查并判断效率低是低到了哪个环节。
测试WebService时,需要注意WebService在第一次初始化的时候有可能会慢。
yyunffu 2008-06-19
  • 打赏
  • 举报
回复
现在通过定位测试,发现问题出在存储过程,去掉第一条判断语句,在按 15楼 方式更改程序,效率现在提高 10 倍以上,达到 0.2秒 级别,虽然还不是最理想,已经有很大改善。
多谢大家帮助!
nec_748 2008-06-19
  • 打赏
  • 举报
回复
yyunffu 2008-06-18
  • 打赏
  • 举报
回复
这个过程是在数据集已经获得,通过循环存入数据库时测试的时间,不包括网络传输时间。
运用的是存储过程方式写入数据库。
存储过程如下:

proc proc_sys_getLetChk --从管理系统下载检查信息
(
@chkDesc varchar(300),
@LetRoomID varchar(20),
@chkTypeID int,
@chkResult int,
@WorkerID varchar(20)
)
as

declare @iErrors int
set @iErrors = 0

--begin tran
if(not exists(select * from CheckItems where LetRoomID = @LetRoomID
and WorkerID = @WorkerID
and chkTypeID = @chkTypeID))
begin
insert into CheckItems(chkDesc,LetRoomID, chkTypeID,chkResult,WorkerID)
values(@chkDesc,@LetRoomID,@chkTypeID,@chkResult,@WorkerID)
set @iErrors = @iErrors + @@error
end
else
begin
update CheckItems
set chkResult = @chkResult,
chkDesc = @chkDesc
where LetRoomID = @LetRoomID
and WorkerID = @WorkerID
and chkTypeID = @chkTypeID
set @iErrors = @iErrors + @@error
end

if(0 != @iErrors)
begin
--rollback tran
return -1
end
else
begin
--commit tran
return 0
end
ld_thinking 2008-06-18
  • 打赏
  • 举报
回复
可能的原因有很多,是db执行sql语句的原因还是ws内执行逻辑的问题,还是网络原因?
yyunffu 2008-06-18
  • 打赏
  • 举报
回复
以上为主要代码,其中,数据行中每一列用如下方式取得:
DataColumn ^dcLetChkDesc = tbChk->Columns[L"rrsiicRemarks"], ^dcLetChkLetID = tbChk->Columns[L"rrsNum"],
^dcLetChkTypeID = tbChk->Columns[L"rrsiicID"], ^dcChkResult = tbChk->Columns[L"rrsiicResult"];


基本情况:
该 WebService 作为中介,介于客户端与后台管理系统之间,由客户端向 Webservice 发起请求,只后WebService 向后台管理系统请求获取数据,后台管理系统结果以 DataSet 参数形式传回。这个客户端是移动设备,WebService 是作为中间层,负责终端与后台系统之间数据交互。

问题:
在获得管理系统数据之后,发现如果数据 在大约 400 条左右,该段入库代码执行大约 2.343 秒 级别。如果在代码前后加事务处理,多人访问该方法时,将发生进程间事务锁定冲突,无法入库。
向各位高手求解:
代码编写是否合理? 如何进行优化,以提高入库效率?

12,162

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 Web Services
社区管理员
  • Web Services社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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