麻烦大家看一下 这个存储过程有需要优化的地方么

不填海的精卫 2014-07-21 01:22:51

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go











--exec [sp_EleRealTime] '00-19-25-b8-17-16',0.00,10,1,1,0,0,0,1,1,1,1,1,1,0,5,'2014-05-05 15:15:15'


-- =============================================
-- Author: <Author,WD、DMY>
-- Create date: <Create Date,20130930,>
-- Description: <Description,实时数据插库,>
-- =============================================

ALTER PROCEDURE [dbo].[sp_EleRealTime]
@MACAddress varchar(40) ,--Mac地址
@speed decimal(18,2) , --速度
@DoorZone bit, --门区
@Fixed bit, --检修
@FireOp bit, --消防操作
@DoorLock bit, --门联锁
@SafeBack bit, --安全回路
@Power bit, --电源
@IsAlarm bit, --故障标志位
@BaseStation bit, --基站信号
@HasPerson bit, --轿厢内有人
@Doorstate bit , --门信号
@DriverState bit, --电梯司机状态
@Dir int , --运行方向
@Floor int , --楼层
@RunTime_Open int , --电梯运行一次时间数据
@ReceiveDate datetime --数据接收时间

AS
BEGIN
declare @ElevatorID int,@pv varchar(50),@v varchar(20), @ef varchar(20),@efnow varchar(20),@newValue varchar(20)
select @ElevatorID=id from B_Elevators where Sign=@MACAddress
select @pv=ParamValue from dbo.S_El_Parameter where ElevatorID=@ElevatorID and ParamName='elevfloor'
set @pv=REPLACE(@pv,'}]','')
set @pv=REPLACE(@pv,'[{totle:','')
set @pv=REPLACE(@pv,'begin:','')
set @pv=REPLACE(@pv,'empty:','')
set @v=dbo.mysplit(@pv,2,',')
set @ef=dbo.mysplit(@pv,3,',')
set @efnow=REPLACE(@ef,'''','')
set @newValue=convert(int,@v)
if(@newValue<0)
begin
if( @Floor<=abs(@newValue))
set @Floor=@Floor+@newValue-1
else
set @Floor=@Floor-abs(@newValue)
end
else if(@newValue=0)
begin
set @Floor=@Floor
end
else if(@newValue>0)
begin
set @Floor=@Floor+@newValue-1
end
if (isnull(@efnow,'')<>'')
begin
set @Floor= dbo.GetRealFloor(@Floor,@efnow)
end
update dbo.R_EleRealTime
set Doorstate=@Doorstate, speed=@speed, Dir=@Dir, Floor=@Floor,
IsAlarm=@IsAlarm,IsFixed=@Fixed,IsFireOp=@FireOp,IsDriver=@DriverState
where Mac=@MACAddress
END









...全文
614 72 打赏 收藏 转发到动态 举报
写回复
用AI写文章
72 条回复
切换为时间正序
请发表友善的回复…
发表回复
不填海的精卫 2014-08-04
  • 打赏
  • 举报
回复
引用 65 楼 Tiger_Zhao 的回复:
list 是一个数据的表。 原先是 C++ 任务列表中的数据,现在这些数据直接人数据库,因为批量插入有快速方法的(SQL Server 批量插入数据的两种方法 ),这样就不需要一条记录一个 UPDATE 了。
例子是用C#写的,C++也一样被?
不填海的精卫 2014-08-04
  • 打赏
  • 举报
回复
引用 65 楼 Tiger_Zhao 的回复:
list 是一个数据的表。 原先是 C++ 任务列表中的数据,现在这些数据直接人数据库,因为批量插入有快速方法的(SQL Server 批量插入数据的两种方法 ),这样就不需要一条记录一个 UPDATE 了。
您给的链接中的方式,用insert代替update了
Tiger_Zhao 2014-08-04
  • 打赏
  • 举报
回复
list 是一个数据的表。
原先是 C++ 任务列表中的数据,现在这些数据直接人数据库,因为批量插入有快速方法的(SQL Server 批量插入数据的两种方法 ),这样就不需要一条记录一个 UPDATE 了。
不填海的精卫 2014-08-04
  • 打赏
  • 举报
回复
引用 59 楼 Tiger_Zhao 的回复:
你调用 SP 的参数 @Doorstate、@speed 还不是从 list 来的,没必要一个个取到程序、再传给 SP。
UPDATE dbo.r_elerealtime
   SET doorstate = list.Doorstate,
       speed = list.speed,
       dir = list.Dir,
       floor = list.Floor,
       isalarm = list.IsAlarm,
       isfixed = list.Fixed,
       isfireop = list.FireOp,
       isdriver = list.DriverState
  FROM dbo.r_elerealtime, list
 WHERE dbo.r_elerealtime.mac = list.MACAddress
   AND list.批号 = @批号 -- 这是 SP 唯一需要的参数
大哥,你说的list 是存储过程参数么? 还是我C++的容器? 我SQL这不专业.麻烦你了
不填海的精卫 2014-08-04
  • 打赏
  • 举报
回复
引用 61 楼 xzb001 的回复:
刚才没注意分隔符是空格,写成逗号分隔了,感觉直接把改写后的语句融合进函数GetRealFloor里比较好,可以去掉双层循环,大概思路是这样的,拆分好字符串的楼层,然后让当前楼层@Floor加上空楼层的数量,就等于修正后的楼层: -- 拆分好字符串,让每个楼层单独一行 with T1 as ( select str = substring(' '+@str, number, charindex(' ', ' '+@str, number+1)-number-1 ) from master.dbo.spt_values where type = 'P' and number between 1 and len(@str) and substring(' '+@str, number, len(@str)) like ' %' ) select newFloor = @Floor + count(case when @Floor >= convert(int, str) then 1 end) from T1
THKS 兄弟~
Tiger_Zhao 2014-08-04
  • 打赏
  • 举报
回复
A)你可以在 list 中加个废弃标志,同一个批次中出现相同 MAC 就把就记录废弃;只用非废弃的做 UPDATE。
B)旧的 MAC 记录直接丢弃不 INSERT。
不填海的精卫 2014-08-04
  • 打赏
  • 举报
回复
引用 70 楼 Tiger_Zhao 的回复:
批量插入100条list 用UPDATE更新100条R_EleRealTime 这是2个操作,比100次UPDATE要优。
不明白的是, 我必须保证每一行的MAC 地址是唯一的,用您那种方法,会冲突吧
Tiger_Zhao 2014-08-04
  • 打赏
  • 举报
回复
批量插入100条list
用UPDATE更新100条R_EleRealTime

这是2个操作,比100次UPDATE要优。
不填海的精卫 2014-08-04
  • 打赏
  • 举报
回复
引用 68 楼 Tiger_Zhao 的回复:
VS.Net 中的 C++ 也可以调用 ADO.Net,否则找找 C++ 调用 bcp insert 的例子。
insert 能代替update么~~
Tiger_Zhao 2014-08-04
  • 打赏
  • 举报
回复
VS.Net 中的 C++ 也可以调用 ADO.Net,否则找找 C++ 调用 bcp insert 的例子。
xiaoxiangqing 2014-08-02
  • 打赏
  • 举报
回复
先监控哪个地方慢,慢的语句可以适当加索引来解决
xzb001 2014-08-02
  • 打赏
  • 举报
回复
刚才没注意分隔符是空格,写成逗号分隔了,感觉直接把改写后的语句融合进函数GetRealFloor里比较好,可以去掉双层循环,大概思路是这样的,拆分好字符串的楼层,然后让当前楼层@Floor加上空楼层的数量,就等于修正后的楼层: -- 拆分好字符串,让每个楼层单独一行 with T1 as ( select str = substring(' '+@str, number, charindex(' ', ' '+@str, number+1)-number-1 ) from master.dbo.spt_values where type = 'P' and number between 1 and len(@str) and substring(' '+@str, number, len(@str)) like ' %' ) select newFloor = @Floor + count(case when @Floor >= convert(int, str) then 1 end) from T1
xzb001 2014-08-02
  • 打赏
  • 举报
回复
尝试改写mysplit函数为查询语句: select str from ( select rn = row_number() over(order by number) , str = substring(','+@str, number, charindex(',', ','+@str, number+1)-number-1 ) from master.dbo.spt_values where type = 'P' and number between 1 and len(@str) and substring(','+@str, number, len(@str)) like ',%' ) x where rn = @sn
Tiger_Zhao 2014-08-01
  • 打赏
  • 举报
回复
你调用 SP 的参数 @Doorstate、@speed 还不是从 list 来的,没必要一个个取到程序、再传给 SP。
UPDATE dbo.r_elerealtime
SET doorstate = list.Doorstate,
speed = list.speed,
dir = list.Dir,
floor = list.Floor,
isalarm = list.IsAlarm,
isfixed = list.Fixed,
isfireop = list.FireOp,
isdriver = list.DriverState
FROM dbo.r_elerealtime, list
WHERE dbo.r_elerealtime.mac = list.MACAddress
AND list.批号 = @批号 -- 这是 SP 唯一需要的参数
不填海的精卫 2014-08-01
  • 打赏
  • 举报
回复
引用 57 楼 Tiger_Zhao 的回复:
没必要啊! 你的 @Doorstate、@speed 已经入了 list,数据库关联更新总比拼 SQL 高效多了。
额 ,还是没听懂您的意思, 我对数据库这不是很熟悉, 能写个代码示例么...
Tiger_Zhao 2014-07-29
  • 打赏
  • 举报
回复
没必要啊!
你的 @Doorstate、@speed 已经入了 list,数据库关联更新总比拼 SQL 高效多了。
不填海的精卫 2014-07-29
  • 打赏
  • 举报
回复
引用 55 楼 Tiger_Zhao 的回复:
讨论方案,哪有正巧有实例的! 收到数据用同一个批号写入列表 数量达到1000条 或 时间达到n秒(看实时要求取 0.1 或 1)   调用 SP   批号++   重置时间 注:时间以批号的第一条记录开始计时。
明白了,那我这样行吧
  update dbo.R_EleRealTime 
    set Doorstate=@Doorstate, speed=@speed, Dir=@Dir, Floor=@Floor, 
	IsAlarm=@IsAlarm,IsFixed=@Fixed,IsFireOp=@FireOp,IsDriver=@DriverState
    where Mac=@MACAddress
我不用存储过程了 , 我直接把每条数据的SQL文拼好,放到一个 list 里,当满足您说的条件时,一起执行 ?
Tiger_Zhao 2014-07-29
  • 打赏
  • 举报
回复
讨论方案,哪有正巧有实例的!

收到数据用同一个批号写入列表
数量达到1000条 或 时间达到n秒(看实时要求取 0.1 或 1)
  调用 SP
  批号++
  重置时间

注:时间以批号的第一条记录开始计时。
發糞塗牆 2014-07-28
  • 打赏
  • 举报
回复
贴全一下,可以先ctrl+t,然后再执行
發糞塗牆 2014-07-28
  • 打赏
  • 举报
回复
sp_help 'R_EleRealTime' 结果贴一下
加载更多回复(52)

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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