Sybase 存储过程耗时过长
Sybase stored procedure taking too long
以下存储过程是 运行 4 小时。无论如何我可以优化它以将执行时间缩短到 10 分钟以下吗?
Table #TbTemp 有 150k 行。并且光标循环了 150k 次。
由于我正在处理临时表,因此我将完全控制创建任何索引等。
既然应该避免使用游标,有什么替代解决方案吗?
declare tmpCur cursor
for
select LnNo,instDrftCreatnDt
from #TbTemp
for read only
open tmpCur
while (1 = 1)
begin --{
fetch tmpCur into @LnNo,@Dt
insert into #TmpLnPmt
(RecTyp,InstNo,LnNo,TotCurChrgdFactr,PmtTyp,
CurrChrgdFactr,CurrPmtAmt,PrevCmptdPmtAmt,NetCmptdPmtAmt)
select '01', @InstNo, @LnNo, @TotCurChrgdFactr, pc.PmtTyp,
0, 0, pc.cmptdPmtAmt, 0-pc.cmptdPmtAmt
from Ln l, Pmt pt, PmtCmpnt pc
where l.LnNo = @LnNo
and pt.mbsLoanPID = l.identifier
and pt.instDrftCreatnDt = @Dt
and pc.paymentComponentsPaymentPID = pt.identifier
and pc.PmtTyp not in (select PmtTyp
from #TbTemp
where LnNo = @LnNo)
and not exists (select 1 from #TmpLnPmt
where LnNo = @LnNo
and PmtTyp = pc.PmtTyp)
end --}
close tmpCur
deallocate cursor tmpCur
这是一种不使用 CURSOR
的方法
INSERT INTO #tmplnpmt
(rectyp,
instno,
lnno,
totcurchrgdfactr,
pmttyp,
currchrgdfactr,
currpmtamt,
prevcmptdpmtamt,
netcmptdpmtamt)
SELECT '01',
@InstNo,
a.lnno,
@TotCurChrgdFactr,
pc.pmttyp,
0,
0,
pc.cmptdpmtamt,
0 - pc.cmptdpmtamt
FROM ln l
INNER JOIN pmt pt
ON pt.mbsloanpid = l.identifier
INNER JOIN pmtcmpnt pc
ON pc.paymentcomponentspaymentpid = pt.identifier
INNER JOIN #tbtemp a
ON l.lnno = a.lnno
AND pt.instdrftcreatndt = a.instdrftcreatndt
WHERE NOT EXISTS (SELECT pmttyp
FROM #tbtemp t
WHERE t.pmttyp = pc.pmttyp)
AND NOT EXISTS (SELECT 1
FROM #tmplnpmt a
INNER JOIN #tbtemp b
ON a.lnno = b.lnno
AND pmttyp = pc.pmttyp)
以下存储过程是 运行 4 小时。无论如何我可以优化它以将执行时间缩短到 10 分钟以下吗?
Table #TbTemp 有 150k 行。并且光标循环了 150k 次。
由于我正在处理临时表,因此我将完全控制创建任何索引等。
既然应该避免使用游标,有什么替代解决方案吗?
declare tmpCur cursor
for
select LnNo,instDrftCreatnDt
from #TbTemp
for read only
open tmpCur
while (1 = 1)
begin --{
fetch tmpCur into @LnNo,@Dt
insert into #TmpLnPmt
(RecTyp,InstNo,LnNo,TotCurChrgdFactr,PmtTyp,
CurrChrgdFactr,CurrPmtAmt,PrevCmptdPmtAmt,NetCmptdPmtAmt)
select '01', @InstNo, @LnNo, @TotCurChrgdFactr, pc.PmtTyp,
0, 0, pc.cmptdPmtAmt, 0-pc.cmptdPmtAmt
from Ln l, Pmt pt, PmtCmpnt pc
where l.LnNo = @LnNo
and pt.mbsLoanPID = l.identifier
and pt.instDrftCreatnDt = @Dt
and pc.paymentComponentsPaymentPID = pt.identifier
and pc.PmtTyp not in (select PmtTyp
from #TbTemp
where LnNo = @LnNo)
and not exists (select 1 from #TmpLnPmt
where LnNo = @LnNo
and PmtTyp = pc.PmtTyp)
end --}
close tmpCur
deallocate cursor tmpCur
这是一种不使用 CURSOR
INSERT INTO #tmplnpmt
(rectyp,
instno,
lnno,
totcurchrgdfactr,
pmttyp,
currchrgdfactr,
currpmtamt,
prevcmptdpmtamt,
netcmptdpmtamt)
SELECT '01',
@InstNo,
a.lnno,
@TotCurChrgdFactr,
pc.pmttyp,
0,
0,
pc.cmptdpmtamt,
0 - pc.cmptdpmtamt
FROM ln l
INNER JOIN pmt pt
ON pt.mbsloanpid = l.identifier
INNER JOIN pmtcmpnt pc
ON pc.paymentcomponentspaymentpid = pt.identifier
INNER JOIN #tbtemp a
ON l.lnno = a.lnno
AND pt.instdrftcreatndt = a.instdrftcreatndt
WHERE NOT EXISTS (SELECT pmttyp
FROM #tbtemp t
WHERE t.pmttyp = pc.pmttyp)
AND NOT EXISTS (SELECT 1
FROM #tmplnpmt a
INNER JOIN #tbtemp b
ON a.lnno = b.lnno
AND pmttyp = pc.pmttyp)