• TADOQuery工作原理


    我不知道你是否知道ADOQuery的工作原理,如果知道的话,请不要怪我啰嗦,ADOQuery有几个重要的属性决定了它的工作模式和工作效率。CursorLocation、CacheSize、CursorType。

            CursorLocation决定了ADOQuery的数据存取模式,它分为Server-side和Client-side两种模式,如果你选择的是Server-side(将CursorLocation属性设为clUseServer)那么当你使用ADOQuery查询数据时,查询的结果将保存在数据源的ADO缓存中或者是存储在数据源本身的缓存中,(如果你的数据源是SQL   Server那末查询的结果将保存在SQL   server的缓存中),数据源只把ADOQuery指定的CacheSize大小的数据传给客户端的ADO引擎,并存储在客户端的ADO缓存中共应用程序处理,如果你指定的CacheSize为10的话那么数据源一次只传回10笔数据给客户端,如果客户端要处理第十一笔数据就需要在向服务器端的ADO引擎申请传递下10笔数据。Client-side模式(clUseClient)则一次将所有的查询结果传回到客户端的ADO缓存中,然后再由客户端ADO   Cursor控制让客户端应用程序处理。Server-side模式将会占用服务器较大的资源,且客户端每处理完一笔数据后就需要向服务器在申请下一笔数据,所以速度较慢,Client-side所有的数据都已传到本地,所以只需要一次传递,以后不再需要向服务器申请,但是在第一次申请时需要传递大量的数据,所以等待的时间较长。一般建议使用Client-side+     StaticCursor的模式,适当的调整CacheSize(500-1000左右)。

          再来看看你的问题,一次查询返回90多万条记录这种查询应该是不合理的,让我们计算一下,如果一条记录长度为100个字节。900*1024*100=90MB!如果你的应用程序与服务器不再同一台机器,90M的数据仅网络传送时间就非常可观了。所以建议使用多次小批量的查询来代替一次查询所有记录的做法,你可以每次只查一天的纪录,查询n次来返回一个月的纪录。实践证明这种查询模式比一次查询所有记录要快(我的实际经验)。

    关于TADOQuery的CacheSize的设置问题
    文章作者 100test 发表时间 2010:02:16 21:43:18
    来源 100Test.Com百考试题网

     

    TADOQuery的CacheSize默认值是1,如果我把它设成1000有什么区别吗?再大点呢?我的数据库中有一万多条记录,发现查询时间较长(通过ADO连SQL Server),哪里需要注意和改进的地方?李维说:设1000比较好cachesize设为1000是比较好的选择,如果你看过李维的ado/mts/com+就知道了,数据原一次传递1000笔数据到客户端,而不是1笔(如果原来你用的是1的话),这样ado的执行效率会比较高。但是我比较了一下,速度一样,看不出什么差别,故有此问难道大家就这么相信李维吗,我认为只有在进行具有绶存的表可以这样做,否则我认为设为 1更好,我就发现,我设为1的速度好象比设为1000更快一些,我是用ADOQuery来打开数据集的不知我的理解是否正确?若其Adoquery的LockType的值設為ItBatchOptiomistic, 改變Cachesize值才有意義,否則Cachesize是不會起作用的。也不是說改得越大越好,還要考慮網絡傳輸的快慢。书上讲的总有些道理的,不然就不会叫他写了. 同上楼上的.。

    adoquery数据缓存
    文章作者 100test 发表时间 2010:02:13 00:59:28
    来源 100Test.Com百考试题网

    请问如何实现adoquery控件提交数据时不直接提交给数据库,提交到缓存。你0select一下不就到到了缓存里了吗,到底要干吗啊我知道的有: 1 申明变量:rs :_Rescordset. 然后把你大数据集克隆给rs,比如: rs =:Adoquery1.Recordset._Xclone,然后你的所有操作都是对这个rs操作.最后再把它提交给数据库还有就是用第三控件非常好用:TRxMemoryData,只要你把你选择出来的字段原样写到里面,对其操作,就行了 ADoQuery1.Locktype := ltBatchOptimistic. ADOQuery1.cachesize := 1000.使用异步模式不就可以了码?设置AdoQuery里面的ExceCuteoptions这个属性你可以看看李维的delphi5的Ado那本书,里面有一章讲这个的我是想说,我用adoquery增加数据,但我想一次增加多条后一次提交给数据库,从而减少网络流量。而不是每增加一条就要提交给数据库。通过 TADOQuery的 RecordSet实现,有空访问 http://java.qxmh.com,呵呵!!!!!我那种就可以啊,你试过了码,我程序就是这么写的大家来接分接分

    使用ADOQuery内存增加的问题
    文章作者 100test 发表时间 2010:01:28 18:42:07
    来源 100Test.Com百考试题网

    使用ADOQuery时发现内存增加,而且将ADOQuery释放后内存不减少(请打开任务管理器,观察内存使用和虚拟内存大小两项,button点击前和点击后的内存变化) button点击事件代码如下:

     L_Query:=Tadoquery.Create(nil). L_Query.Connection:=ADOConnection1. //Form上的一个控件

     L_Query.SQL.Text:= Select * from equipments . //该数据为2万行左右 L_Query.ExecSQL. //L_Query.Close. FreeAndNil(L_Query).

     我在使用过程中,有大量的数据量大的数据表,所以内存一直在增加而不能释放,问题很严重,导致内存不足。求原因和解决办法。谢谢!

    L_Query.CussorLocation :=clUseServer 使用服务器端游标,这样ADO就不缓存记录谢谢xiaoyin!

     但是我分别尝试过下面的三条语句,结果还是一样的。内存一点都不少 // L_Query.CursorLocation:=clUseServer. // L_Query.CursorLocation:=clUseClient. //L_Query.MaxRecords:=1000.郁闷,

    一直解决不了这个问题~!L_Query.free. 这个不知道可不可以!谢谢delphi_zys, 使用L_Query.free.效果还是一样!郁闷啊~救救我吧 try L_Query:=Tadoquery.Create(nil). L_Query.Connection:=ADOConnection1. //Form上的一个控件 L_Query.SQL.Text:= Select * from equipments . //该数据为2万行左右 L_Query.ExecSQL. finally L_Query.free. L_Query:=nil. end. 使用ADOQuery时发现内存增加,而且将ADOQuery释放后内存不减少(请打开任务管理器,观察内存使用和虚拟内存大小两项,button点击前和点击后的内存变化) button点击事件代码如下: L_Query:=Tadoquery.Create(nil). try L_Query.Connection:=ADOConnection1. L_Query.SQL.Text:= Select * from equipments . //该数据为2万行左右 L_Query.ExecSQL. ///应该这样L_Query.Open. //L_Query.Close. finally //用完最好close FreeAndNil(L_Query). end.谢谢DIGUA,andrew57。 To DIGUA:FreeAndNil和分别使用Free和Nil的作用是一样的。当然,我也抱着希望试了一下,结果还是一样没有变化。 To andrew57:Open方法是返回结果集,ExecSQL是不返回结果集合。尝试了一下,内存占用更多了。另:try finally语句对内存不存在直接的影响。尝试后结果一样。楼主,我试了,创建自身是可以的这样 procedure TForm1.Button1Click(Sender: TObject). var L_Query:TADOQuery. begin try L_Query:=Tadoquery.Create(self). ******这里参数用self,别用nil L_Query.Connection:=ADOConnection1. //Form上的一个控件 L_Query.SQL.Text:= Select * from tmp .//该数据为2万行左右 L_Query.ExecSQL. finally L_Query.Close. L_Query.free. L_Query:=nil. end. end.请楼主无论行否都给个话,关注谢谢DIGUA。我尝试了你的方法,情况没有改变。我现在提供另外一部分的辅助代码,帮助理解。 1.第一部分函数的目的是得到进程的物理内存使用 虚拟内存 2.第二部分按钮点击事件是直接释放物理内存的代码(但是必须为2003或xp系统!) 3.在程序最小化的时候内存是变小了的!!! 4.我想知道的是,怎样才能不使用第二部分的代码或最小化的情况下,将我不再使用的内存释放出来!为什么现在的正常释放掉控件但是内存不释放呢?这到底是一种怎么样的机制或是内存策略呢?实在是不解! 请先引用三个单元:psapi,shellapi,TLHelp32 第一部分函数: //得到当前的物理内存、虚拟内存的方法 function TForm1.GetCurrMemory:integer. var lppe: TProcessEntry32. //用于获取每个进程信息结构 found : boolean. Hand : THandle. pmc:PPROCESS_MEMORY_COUNTERS.//uses psApi prohandle: HWND. cb: DWORD. begin lppe.dwSize:=SizeOf(lppe). cb := SizeOf(_PROCESS_MEMORY_COUNTERS). GetMem(pmc, cb). pmc^.cb := cb. prohandle :=OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,False,GetCurrentProcessId).//由PID取得进程对象的句柄 if GetProcessMemoryInfo(prohandle, pmc, cb) then begin Result:=pmc^.PagefileUsage pmc^.WorkingSetSize. end. FreeMem(pmc). end. 第二部分,按钮点击事件 procedure TForm1.Button4Click(Sender: TObject). begin //WinXp,Win2003使用释放物理内存 if Win32Platform = VER_PLATFORM_WIN32_NT then begin SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF). application.ProcessMessages. end. end. 晕了,都没仔细看,楼着你0select * from 应该用L_Query.open. 不是L_Query.ExecSQL.Open方法是返回结果集,ExecSQL是不返回结果集合。尝试了一下Open,内存占用更多了。。

    再次质疑CacheSize:

    ---------------------------------------------------------------

    ADOQuery的属性设置如下:

      CursorLocation:= clUseClient;

      CursorType:= ctKeySet;

      LockType:= ltBatchOptimistic;

      CacheSize:= 100;

      SQL.Text:= 'Select * from companys';

      MaxRecords:= 0;

     

    companys表有一万条测试记录.

    adoquery.open后程序占34兆内存,设定

      MaxRecords:= 100;

    再次adoquery.open后程序只占有8兆内存.

     

    很显然在这里CacheSize没有起到任何作用,所有的记录仍然全部被缓存到

    本机.

     

    测试环境:

      Win2000Pro, D6,ADO2.7,SQL SERVER 2K.

    有一个表中数据有几十万条,如果一次性显示所有记录的实在是太慢了,请问有没有办法如下:先显示前十条记录,然后点击下一页显示下十条记录,再点击下一页的时候再显示下十条记录,以此类推!
    请问没有没办法?  

    1、select * from pubs..employee order by emp_id
    2、adoquery1.Open;
    3、adoquery1.Recordset.PageSize:=10;
    4、adoquery1.Recordset.AbsolutePage:=2;
    5、if adoquery1.Recordset.AbsolutePage<adoquery1.Recordset.pagecount then
       adoquery1.Recordset.AbsolutePage:=adoquery1.Recordset.AbsolutePage+1;  

    1、改ADOQuery的CacheSize:=ClientDataSet.PacketRecord
                   CursorLocation:=alUseClient
                   CursorType:=ctStatic
                   LockType:=ltOptimistic/ltBatchOptimistic
       这样就能加快你的速度。(CacheSize最好小于900条记录)。
     
    2、AdoQuery用Select To n * from [表] where ....
       改ClientDataSet.FetchOnDemand的属性为False
       自己取数据集。
  • 相关阅读:
    接口测试再思考
    Python开发简单爬虫
    正则表达式(Python)
    Git常用方法
    CNN--卷积神经网络从R-CNN到Faster R-CNN的理解(CIFAR10分类代码)
    一看就懂的K近邻算法(KNN),K-D树,并实现手写数字识别!
    我是这样一步步理解--主题模型(Topic Model)、LDA(案例代码)
    你想知道的特征工程,机器学习优化方法都在这了!收藏!
    从似然函数到EM算法(附代码实现)
    一次性弄懂马尔可夫模型、隐马尔可夫模型、马尔可夫网络和条件随机场!(词性标注代码实现)
  • 原文地址:https://www.cnblogs.com/msony924840/p/4876419.html
Copyright © 2020-2023  润新知