查询用了我30分钟,大家快帮忙

niaoren 2005-04-07 02:47:47
现在有:
设备表,试验项目表,试验周期表,试验计划表

现在要根据试验项目生成设备的试验计划

关系:
设备(1)->试验项目(n)
试验项目(1)->试验周期(n)

我写了一个存储过程,里面嵌套了3个游标,生成5000条计划用了我30分钟,大家给点意见
...全文
278 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
云中客 2005-09-07
  • 打赏
  • 举报
回复
尽量别用游标,特别是嵌套,肯定慢。想想用临时表能否实现
zzxiaoma 2005-09-03
  • 打赏
  • 举报
回复
存储过程不要写的太复杂了,能用程序就用程序
特别是游标不要嵌套
pingfzp 2005-04-12
  • 打赏
  • 举报
回复
如:
INSERT INTO 表变量(.....)
SELECT ....
FROM 试验周期表 INNER JOIN
试验项目表 ON .......... INNER JOIN
设备表 ON........
WHERE ....................

--更新
INSERT INTO 试验计划表(.........)
SELECT ..........
FROM 表变量
WHERE 表变量.PeriodUnit = 1--月
AND ...........
..........
..........

pingfzp 2005-04-12
  • 打赏
  • 举报
回复
大哥,看你的存储过程有点晕呀,同意大伙意见:不要使用游标!切记!!!切记!!!
赞成rabbit9(野兔) 意见:用表这是或临时表替换游标。

个人建议:
把你需要的数据先SELECT出来放到一个表变量中,然后再从表变量中过滤出你要插入到试验计划表的数据,当然这需要你的表结构的支持
如:
SELECT ....
FROM 试验周期表 INNER JOIN
试验项目表 ON ..........


设备表,,
rabbit9 2005-04-12
  • 打赏
  • 举报
回复
晕,同一个表操作,10个线程比单线程更慢。
还是优化你的存储过程吧,游标是性能杀手。
5000条一个游标就可以让你爆血管,还三个嵌套。
有高楼的话就站在最顶层想,想不出来也有解决的办法。
woodcord 2005-04-12
  • 打赏
  • 举报
回复
不用游标

设置一个跟踪看看到底是哪儿用时间多啊??
niaoren 2005-04-12
  • 打赏
  • 举报
回复
我采用程序实现,而且是10个线程运行,速度还是不行,可能是我设计有问题?但是现在已经改变不了了,哪位大侠帮我优化一下,谢谢了!
rabbit9 2005-04-08
  • 打赏
  • 举报
回复
尽量别用游标,你用了几层嵌套,肯定慢。想想用临时表能否实现?
niaoren 2005-04-08
  • 打赏
  • 举报
回复
主要是需要插入很多数据,可能有几千条
pingwing 2005-04-08
  • 打赏
  • 举报
回复
支持楼上的意见,不用游标
niaoren 2005-04-07
  • 打赏
  • 举报
回复
大家给电意见,用什么方法比较快一些?
zierben 2005-04-07
  • 打赏
  • 举报
回复
sqlserver 的原则就是不要用一个游标
niaoren 2005-04-07
  • 打赏
  • 举报
回复
在程序里面实现会快一些吗?因为里面有很多查询操作,而且还insert操作
malamala 2005-04-07
  • 打赏
  • 举报
回复
劝你别用存储过程,用编程语言也许很快就搞定了
wyb0026 2005-04-07
  • 打赏
  • 举报
回复
大爷优化一下别用游标
niaoren 2005-04-07
  • 打赏
  • 举报
回复
我写的存储过程,大家帮我想想办法,不知道还有没有其他办法解决

CREATE proc [dbo].PreventivePlan
@CompanyID int, --公司ID
@StartTime datetime, --开始时间 e.g. '2005-1-1'
@EndTime datetime --结束时间 e.g. '2007-1-1'
as
declare @CurrentDateTime datetime --当前时间
set @CurrentDateTime=GetDate()
--临时变量
declare @IsPeriod bit --找到匹配的周期
declare @TempStartTime datetime,@TempEndTime datetime --临时时间变量

--试验项目编号
declare @ExpSubTypeID int --次类ID
declare @ExpProjectID int --试验项目ID
declare @Status int,@StartDate datetime, @EndDate datetime
declare @PeriodID int, @Period int, @PeriodUnit int, @Vol int, @AfterYear int --周期时间,周期单位,电压等级,运行年份
declare @count int

--查询设备公共参数
declare @RuningYear int --设备的运行年份


declare @EquipmentID int,@EquipmentVol int, @EquipmentBuyDate datetime, @EquipmentStartDate datetime --设备ID,电压等级,设备购买时间,开始使用日期
declare Equip cursor local for
select 设备编号,电压等级,购置日期,开始使用日期 from gdzhdb.dbo.设备索引 a inner join jsjdDB.dbo.expequipment b on a.[设备编号]=b.[ID] where 归口单位编号 = @CompanyID
open Equip --打开设备表
fetch next from Equip into @EquipmentID,@EquipmentVol,@EquipmentBuyDate,@EquipmentStartDate
while @@fetch_status=0 --获取到一个设备
begin
set @RuningYear=year(@CurrentDateTime)-year(@EquipmentStartDate)

--查询设备试验次类

select @ExpSubTypeID=ExpSubTypeID from expequipment where [ID] = @EquipmentID

--查询试验设备所拥有的试验项目,遍历试验项目

declare project cursor local for
select [ID] from ExpProject where ExpSubTypeID = @ExpSubTypeID
open project
--遍历试验项目
fetch next from project into @ExpProjectID
while @@fetch_status = 0 --获取到一个试验项目
begin
--print '项目ID为'
--print @ExpProjectID
--试验计划表

set @Status = null
set @StartDate = null
set @EndDate = null

--试验周期 --循环遍历试验周期

declare subProject cursor local for
select [ID],Period, PeriodUnit, Vol, AfterYear from ExpPeriod where ExpProjectID = @ExpProjectID
open subProject
--判断试验周期是否符合要求,
fetch next from subProject into @PeriodID,@Period, @PeriodUnit, @Vol, @AfterYear
while @@fetch_status = 0
begin
--print '周期ID为'
--print @PeriodID
--更新
if @PeriodUnit = 1 --月
begin
--select @Status=Status, @StartDate=StartDate, @EndDate=EndDate from expplan where ExpEquipmentID = @EquipmentID and ExpProjectID = @ExpProjectID and EndDate = (select max(EndDate) from expplan where ExpEquipmentID = @EquipmentID and ExpProjectID = @ExpProjectID)

set @IsPeriod=dbo.GetPeriod(@Period, @PeriodUnit, @Vol, @AfterYear,@RuningYear,@EquipmentVol)
if @IsPeriod = 1
begin
set @TempStartTime = @StartTime
set @TempEndTime = DateAdd(day,-1,DateAdd(month,@Period,@TempStartTime))
while(@TempEndTime<@EndTime)
begin

select @count=count(ID) from expplan where ExpEquipmentID = @EquipmentID and @ExpProjectID = ExpProjectID and @TempStartTime=StartDate and @TempEndTime=EndDate and ExpProperty=3
if @count=0
begin
insert into ExpPlan (ExpEquipmentID,ExpProjectID,ExpPeriodID,StartDate,EndDate,Creator,CreateDate,ExpProperty,Status) values (@EquipmentID,@ExpProjectID,@PeriodID, @TempStartTime, @TempEndTime,'系统',GetDate(),3,3)
end
set @TempStartTime = DateAdd(month,@Period,@TempStartTime)
set @TempEndTime = DateAdd(day,-1,DateAdd(month,@Period,@TempStartTime))
end
break --找到符合条件的周期,插入数据后退出
end
end
else if @PeriodUnit = 0 --年
begin
select @Status=Status, @StartDate=StartDate, @EndDate=EndDate from expplan where ExpEquipmentID = @EquipmentID and ExpProjectID = @ExpProjectID and EndDate = (select max(EndDate) from expplan where ExpEquipmentID = @EquipmentID and ExpProjectID = @ExpProjectID)
if (@Status >= 4 and @Status < 7) or @EndDate is null --是否需要生成试验计划。当状态为4已试验,5已填报,6已取消 时,或者EndDate =null (没有生成过试验计划)时,生成新试验计划。
begin
set @IsPeriod=dbo.GetPeriod(@Period, @PeriodUnit, @Vol, @AfterYear,@RuningYear,@EquipmentVol)
if @IsPeriod = 1
begin
--print '添加年周期'
insert into ExpPlan (ExpEquipmentID,ExpProjectID,ExpPeriodID,StartDate,EndDate,Creator,CreateDate,ExpProperty,Status) values (@EquipmentID,@ExpProjectID,@PeriodID, @StartTime, DateAdd(day,-1,DateAdd(year,@Period,@StartTime)),'系统',GetDate(),3,3)
break --找到符合条件的周期,插入数据后退出
end
end
end
fetch next from subProject into @PeriodID,@Period, @PeriodUnit, @Vol, @AfterYear--下一条
end
close subProject
deallocate subProject
fetch next from project into @ExpProjectID --下一条
end
close project
deallocate project
fetch next from Equip into @EquipmentID,@EquipmentVol,@EquipmentBuyDate,@EquipmentStartDate
end
close Equip
deallocate Equip
if @@error <>0
return 0
else
return 1
GO

11,849

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 非技术版
社区管理员
  • 非技术版社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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