日期:2014-05-18  浏览次数:20821 次

存储过程占用大量内存,完成后怎么释放?
我现在管的这服务器每天会向另一个数据库服务器提交一次数据,具体的存储过程如下:
SET   QUOTED_IDENTIFIER   ON  
GO
SET   ANSI_NULLS   ON  
GO

ALTER                             PROCEDURE   DUMP_GIS_DYH   --@DATETIME   DATETIME
AS
BEGIN
      DELETE   FROM   MIDGZDL..MIDGZDL.FQD_TRANS_DL   WHERE   CONVERT(CHAR(10),DATATIME,120)=CONVERT(CHAR(10),GETDATE()-1,120)  
      DELETE   FROM   MIDGZDL..MIDGZDL.FQD_TRANS_DLXX   WHERE   CONVERT(CHAR(10),DATATIME,120)=CONVERT(CHAR(10),GETDATE()-1,120)    

      INSERT   INTO   MIDGZDL..MIDGZDL.FQD_TRANS_DL(USERID,AMMETERID,DATATIME,DATAY,DATAW)
      Select   a.NUMBER,MIN(a.EMNO),b.YearMonthDay,ISNULL(MAX(b.PositiveDailyData),0),ISNULL(MAX(b.NegativeDailyData),0)
      from   EUSER   a,erimis.DBO.newMeasureSetDailyData   b  
      where   a.termno=CAST(b.MEASURESETID   AS   INT)   and   datediff(day,b.YearMonthDay,GETDATE())=1  
        and   (b.PositiveDailyData=b.NegativeDailyData   and   b.PositiveDailyData <> 0   )
      GROUP   BY   a.NUMBER,b.YearMonthDay


      INSERT   INTO   MIDGZDL..MIDGZDL.FQD_TRANS_DLXX(USERID,AMMETERID,DATATIME,DATAIA,DATAIB,DATAIC,DATAUA,DATAUB,DATAUC,DATASUM,CREST,TROUGH,BALANCE)
select   a.number,min(a.emno),d.DT,
ISNULL(max(d.ia),0)*min(a.ctpt),ISNULL(max(d.ib),0)*min(a.ctpt),ISNULL(max(d.ic),0)*min(a.ctpt),ISNULL(max(d.ua),0),ISNULL(max(d.ub),0),ISNULL(max(d.uc),0),ISNULL(max(d.PRATIOTOTAL),0),ISNULL(max(d.ZY_FDL),0),ISNULL(max(d.ZY_GDL),0),ISNULL(max(d.ZY_PDL),0)
from   euser   a,afn0d_all   d
where   a.termno=d.termno   and   datediff(day,d.dt,GETDATE())=1
GROUP   BY   a.number,d.DT


END  


GO
SET   QUOTED_IDENTIFIER   OFF  
GO
SET   ANSI_NULLS   ON  
GO

其中要提到的是:afn0d_all数据量比较大,又200多万条记录;
在存储过程执行时,内存占用量以每秒8M左右增加,直到1.5--1.6G,服务器总内存为3G多,但是CPU却只在0---5间变动。原来因为一般都是成功的,所以我也没去注意,但是这段时间却频频失败,提示为:数据库已用完了提供的内存,内存量不足云云。
        今天又执行了几遍,偶尔一次居然成功了,但是看执行完成后,内存占有量还是保持在1.6G始终降不下来
        请问各位高人1.不就是几个条件删除,然后条件插入吗,数据量也不大啊,怎么会暂用这么多的资源?
                                2.为什么执行完成后却不释放,怎么能让它释放?
小弟对SQL不怎么懂,可能有重点没说到,有不明白的地方说下,我在线解释,谢谢!!!




------解决方案--------------------
首先你的内存下了点,服务器只有3G,现在个人电脑很多都2G了

重要的一点是你SqlServer的tmpdb数据库不知道放在那里磁盘里,空间够不够,存储过程会占用内存,但不会太多,主要是依靠tmpdb数据库做中转,估计是你的磁盘空间也不够大了

释放都是自动的,另外重启SqlServer服务也能释放
------解决方案--------------------
200万条数据insert,会产生很大的LOG 文件,估计是你的磁盘不够了.如果想大数据操作,可以设置数据库为简单模式,看看.
------解决方案--------------------
你的delete,insert操作操作的记录数太多了,分批进行吧.
------解决方案--------------------
tempdb是一部分原因。数据占用的内存也是可以清除的。
------解决方案--------------------
看看你的JOIN连接的执行计划,看看是否有可以优化的地方。