数据采集服务程序--ADO连续插入记录,2天后,插入速度明显变慢,求解原因?

Delphi7 + SQL2000 + CPU3.0G + 内存1.5G + 分区30G + Windows2003系统

SQL缓冲区200M, 插入控件ADOQuery, 直接插入,不用存储过程。

以单线程执行操作。
以每秒中插入200条记录的速度,连续插入。
每插入200条,Sleep10毫秒。 

刚开始1天左右,插入的速度都很正常,可2天后,插入的速度就变的很慢了。

求高手给于帮助啊?
----------------------------------------------
-
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
盒子中级会员
2006-7-31 20:35:27
1楼: 不知道原因(因为没试过),不过资料上说,对数据量大的用存储过程性能最好。
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河)
作者:
男 yuqunhua1982 (123) ▲△△△△ -
普通会员
2006-8-1 19:53:57
2楼: 数据量大,可能指的是 单条记录的信息包含量比较大吧。
而我这里的单条记录的信息包含量并不大。只是实时性比较高,1秒要插入200条左右的记录;而且持续时间比较长,程序可能要执行半年,或者1年。
考虑到上面的几个因素,所有我才不用存储过程,而用ADOQuery直接插入。
不知道这样考虑对不对啊?
----------------------------------------------
-
作者:
男 gbm_pgs (编程之道) ▲▲△△△ -
盒子活跃会员
2006-8-1 20:13:08
3楼: 用存储过程也是一样的,这跟你的程序使用多久无关吧!
----------------------------------------------
寂静的虚空里诞生了神秘的东西,这种东西恒久存在永不消失,它是所有程序的根源所在,我不知道怎么形容它,姑且称它为编程之道!
作者:
男 yuqunhua1982 (123) ▲△△△△ -
普通会员
2006-8-2 10:22:18
4楼: 那譬如说 2个字段的表格 
Table_XXX( ID Int, Name Varchar(20))

每秒向这个表格中连续插入400条记录,是使用存储过程好呢,还是直接用AODQUERY插入比较好啊。

首先,在这种情况下,CPU的利用率会比较高,因为中间是连续插入的(虽然在插入一定的次数后用了SLEEP(10)语句);再者,我发现用存储过程插入的速度竟然要比直接插入的速度慢,不解。

我的TADOQuery直接插入方式为
 with ADOQry do
 begin
   Close;
   SQL.Clear;
   SQL.ADD('Insert...');
   SQL.ExecSQL;
 end;

我的存储过程方式为:
 with self.ADOProc do
 begin
   Close;
   ProcedureName := 'Proc_Insert_Last_Data_BatGroup_Vol_D';
   Parameters.Refresh;
   Parameters.ParamByName('xx').Value := xx;
   ...
   ExecProc;
 end;

还有,我发现用TADOTable来插入的话,数据量一大,肯定玩完。
  with ADOTable do
  begin
    Open ;
    Insert;
    FieldByName(‘xx').AsInteger:= xx;
    ...
    Post;
    Close;
  end;

请问这三种插入的方法的本质区别在哪里啊?
还有没有其他更好的插入方法啊?
----------------------------------------------
-
作者:
男 shuihan20e (shuihan) ▲▲△△△ -
盒子活跃会员
2006-8-2 10:39:03
5楼: 如此大的数据量我没试过,不过我感觉还是用SP要快,尤其是你的数据量非常大的时候,不只是指单条记录的数据量,还有表中数据量非常大的时候,如果真有如此大的数据量为什么不尝试下ORACLE
----------------------------------------------
If I could rearrange the alphabet, I would put U and I together!!!www.objectsoft.cn
作者:
男 yuqunhua1982 (123) ▲△△△△ -
普通会员
2006-8-3 16:47:55
6楼:   终于发现问题了。原来当数据库文件大于20G的时候,会发生SQL2000进程SPID堵塞的情况,导致SQL2000插不进记录的情况。
  有没有办法不会发生堵塞啊?还有,怎么才能解除已经产生的堵塞情况啊?
  还有,当要清空20G以上的数据库文件内的记录,用查询分析器的话,都要话上1个小时,有没有其他更好的方法啊?
----------------------------------------------
-
作者:
男 neoyao (neoyao) ▲▲△△△ -
盒子活跃会员
2006-8-3 21:12:45
7楼: 有办法:
1、使用sqlserver2005 enterprise;
2、是否你的sqlserver2000有问题?sp4打了没?或是装的有问题?
因为:
我的数据量比你的大得多,数据库文件180G,没有任何问题;以前用sqlserver2000没问题,后来升级到sqlserver2005,更没问题了,而且速度暴快,目前数据采集服务程序连续运行1个月了都没问题,sqlserver2005更是稳定,迄今半年没重启机了。
----------------------------------------------
-
作者:
男 neoyao (neoyao) ▲▲△△△ -
盒子活跃会员
2006-8-3 21:14:30
8楼: 另外问一下,我是做通信的,所以数据量大;你是做什么方面的系统?
----------------------------------------------
-
作者:
男 yuqunhua1982 (123) ▲△△△△ -
普通会员
2006-8-4 12:05:25
9楼: 我是电力方面的,采集的数据都是电压、电流之类的。

现在的问题是,当数据量大于50G的时候,仅仅删除记录是怎么处理的啊(在不动数据库表格的情况下)。

如果把删除记录的功能写成Delphi程序来删除的话,用ADOQuery,会不会出现异常啊(删除一个表格的记录可能要1小时啊)。

如果用SQL自带的查询分析器,这样
Use XXX
go

Delete From XXX1
go

Delete From XXX2
go

...

这样用SQL教本来执行的话,会死SQL的啊
----------------------------------------------
-
作者:
男 ls_d88 (拖鞋) ▲△△△△ -
普通会员
2006-8-4 17:22:06
10楼: 看你数据采集下来是怎么处理的了。
你可以做个程序每星期五对数据进行维护下。
----------------------------------------------
-
作者:
男 liangkan (小冰) ▲△△△△ -
普通会员
2006-8-4 23:50:27
11楼: 关注,请继续讨论
----------------------------------------------
难者不会,会者不难。
作者:
男 andyfurong (听说昵称最长二十个汉字或四十个英文,我就不信只能取这么长的昵称,帮我数数看有多少) ▲▲△△△ -
盒子活跃会员
2006-8-6 15:25:13
12楼: 以前看过一篇文章,数据量很大的表要删除的的话最好是分批删(Oracle),速度提高N倍
----------------------------------------------
我想我是海论坛:编程技巧,聊天交友  http://andyfurong.9126.com
作者:
男 neoyao (neoyao) ▲▲△△△ -
盒子活跃会员
2006-8-6 22:33:51
13楼: 好吧,继续讨论:
删除也是非常简单的,我的做法是,由于数据入库都有时间标记,例如我的数据要保留3个月,所以每天凌晨删除3个月之前的,在作业里定义:Delete from xxx where DataTime(表里的时间字段)<=DATEADD(mm, -3, GETDATE());就行了。
----------------------------------------------
-
作者:
男 neoyao (neoyao) ▲▲△△△ -
盒子活跃会员
2006-8-6 22:36:22
14楼: 你的意思我没看懂,是清空表?所以delete from xxx1;delete from xxx2?那不直接用truncate table xxx1就完了吗?!
----------------------------------------------
-
作者:
男 yuqunhua1982 (123) ▲△△△△ -
普通会员
2006-8-7 13:10:11
15楼: truncate 是把表格中的记录全部清空。我这个程序中有2个地方要涉及到数据记录的清除或者修改。

一。第一种情况,我要清除某个月以前的历史数据记录,但是还是要保存那个月的数据记录,譬如,当前的年月是2007年1月了,我要清除2007年1月以前的数据,所以要用neoyao所说的Delete from xxx where DataTime < xxxx这种方法,而不能用truncate。

二。第二种情况,(我用一个例子来说明:假设现在有个学生管理系统,里面总共有3个班级信息。现在我删除了里面某个班级的信息,当然我也要同时级联删除那个班级的所有学生的考试成绩信息。) 我现在所做的程序也是类似情况,不过就是‘那个班级的所有学生的考试成绩信息’都将近有10G左右的数据。

针对上面这2种情况。我想到的解决删除10G以上的数据库表格记录信息的方法:

一:直接在程序里面创建一个新线程,用ADOQuery.SQL.ADD('Delete from xxx where DataTime')来执行。不过这样,我担心的是由于超时(1小时以上的删除)会不会造成SQL SERVER2000‘没响应’的异常情况的产生。

二:自己做一个外部的数据库删除程序,在主程序执行删除操作时,调用这个数据库删除程序来删除级联信息。 这个数据库删除程序使用存储过程ADOStoredProc来执行。(其实就是用存储过程来解决)

三:调用SQL SERVER 2000自身附带的查询分析器工具来删除,还是用Delete from xxx where DataTime语句,一个表格一个表格的删除。不过,好像也会操作超时,导致SQL没相应。

四:索性不删除那些级联记录(这个是在万般无奈的情况下采取的措施。因为程序的稳定第一啊 ^_^ )

大家看看,哪种方法好一点啊。不知道还有没有其他更好的方法推荐啊?

----------
在这里对于大家的热情帮助,表示万分感谢!
----------------------------------------------
-
作者:
男 gbm_pgs (编程之道) ▲▲△△△ -
盒子活跃会员
2006-8-8 14:12:09
16楼: 给你一个建义,对你提高速度来说是有很大的帮助:
 1:给所有要操作的表增加索引Create index...
 2 对于数据量大的尽量用存储过程ADOCon.Execute('exec P_SProc');
 3.做成永久性的SQL,执行时只传参数.执行前先 Prepare;以便加快速度!
 4.清空表用 Truncate table .而不用delete ...(因为delete 是要记日志log的)
优化后相信你的速度会提高一倍!
----------------------------------------------
寂静的虚空里诞生了神秘的东西,这种东西恒久存在永不消失,它是所有程序的根源所在,我不知道怎么形容它,姑且称它为编程之道!
作者:
男 gbm_pgs (编程之道) ▲▲△△△ -
盒子活跃会员
2006-8-8 14:18:00
17楼: 还是,SQL2K单个文件的大小最大20G,20G之后一般都会崩溃,这是SQL的一个问题,如且大的数据每天最好要对数据库进行优化,DBCC ..,Dump log ...等操作,不过还是用2005算了,因为2005已支持超过20G了
----------------------------------------------
寂静的虚空里诞生了神秘的东西,这种东西恒久存在永不消失,它是所有程序的根源所在,我不知道怎么形容它,姑且称它为编程之道!
作者:
男 iwizard (lxy) ▲△△△△ -
普通会员
2006-8-8 16:23:27
18楼: 呵呵,我的建议关于索引部分正好和16楼相反,插入数据表不应该有任何索引。只有对其进行查询处理时才应该建立索引,而且如果是集群索引,随着数据量的增加,只能使插入操作越来越慢。可以看看李维的《delphi高效率数据库开发》最后几节有讲和楼主类似的情形。

具体的我没有做过,只是建议。

你可能感兴趣的:(数据)