您的位置:首页 > 产品设计 > UI/UE

TADOQuery工作原理

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

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

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

关于TADOQuery的CacheSize的设置问题

文章作者100test发表时间2010:02:1621:43:18

来源100Test.Com百考试题网

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

adoquery数据缓存

文章作者100test发表时间2010:02:1300: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:2818:42:07

来源100Test.Com百考试题网

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

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

L_Query.SQL.Text:=
Select*fromequipments. //该数据为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*fromequipments. //该数据为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*fromequipments
. //该数据为2万行左右L_Query.ExecSQL.
///应该这样L_Query.Open.//L_Query.Close.finally//用完最好closeFreeAndNil(L_Query).end.谢谢DIGUA,andrew57。ToDIGUA:FreeAndNil和分别使用Free和Nil的作用是一样的。当然,我也抱着希望试了一下,结果还是一样没有变化。To
andrew57:Open方法是返回结果集,ExecSQL是不返回结果集合。尝试了一下,内存占用更多了。另:tryfinally语句对内存不存在直接的影响。尝试后结果一样。楼主,我试了,创建自身是可以的这样procedure
TForm1.Button1Click(Sender:TObject).varL_Query:TADOQuery.begintry
L_Query:=Tadoquery.Create(self).******这里参数用self,别用nilL_Query.Connection:=ADOConnection1.//Form上的一个控件L_Query.SQL.Text:=Select*fromtmp.//该数据为2万行左右L_Query.ExecSQL.finallyL_Query.Close.L_Query.free.L_Query:=nil.
end.end.请楼主无论行否都给个话,关注谢谢DIGUA。我尝试了你的方法,情况没有改变。我现在提供另外一部分的辅助代码,帮助理解。1.第一部分函数的目的是得到进程的物理内存使用虚拟内存2.第二部分按钮点击事件是直接释放物理内存的代码(但是必须为2003或xp系统!)3.在程序最小化的时候内存是变小了的!!!4.我想知道的是,怎样才能不使用第二部分的代码或最小化的情况下,将我不再使用的内存释放出来!为什么现在的正常释放掉控件但是内存不释放呢?这到底是一种怎么样的机制或是内存策略呢?实在是不解!
请先引用三个单元:psapi,shellapi,TLHelp32第一部分函数://得到当前的物理内存、虚拟内存的方法function
TForm1.GetCurrMemory:integer.varlppe:TProcessEntry32.//用于获取每个进程信息结构found:boolean.Hand:THandle.
pmc:PPROCESS_MEMORY_COUNTERS.//usespsApiprohandle:HWND.cb:DWORD.begin
lppe.dwSize:=SizeOf(lppe).cb:=SizeOf(_PROCESS_MEMORY_COUNTERS).GetMem(pmc,
cb).pmc^.cb:=cb.prohandle:=OpenProcess(PROCESS_QUERY_INFORMATIONor
PROCESS_VM_READ,False,GetCurrentProcessId).//由PID取得进程对象的句柄ifGetProcessMemoryInfo(prohandle,pmc,cb)thenbegin
Result:=pmc^.PagefileUsagepmc^.WorkingSetSize.end.FreeMem(pmc).end.第二部分,按钮点击事件procedureTForm1.Button4Click(Sender:TObject).begin
//WinXp,Win2003使用释放物理内存ifWin32Platform=
VER_PLATFORM_WIN32_NTthenbeginSetProcessWorkingSetSize(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*fromcompanys';

MaxRecords:=0;

companys表有一万条测试记录.

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

MaxRecords:=100;

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

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

本机.

测试环境:

Win2000Pro,
D6,ADO2.7,SQLSERVER2K.

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

请问没有没办法?

1、select*frompubs..employeeorderbyemp_id

2、adoquery1.Open;

3、adoquery1.Recordset.PageSize:=10;

4、adoquery1.Recordset.AbsolutePage:=2;

5、ifadoquery1.Recordset.AbsolutePage<adoquery1.Recordset.pagecountthen

adoquery1.Recordset.AbsolutePage:=adoquery1.Recordset.AbsolutePage+1;

1、改ADOQuery的CacheSize:=ClientDataSet.PacketRecord

CursorLocation:=alUseClient

CursorType:=ctStatic

LockType:=ltOptimistic/ltBatchOptimistic

这样就能加快你的速度。(CacheSize最好小于900条记录)。


2、AdoQuery用SelectTon*from[表]where....

改ClientDataSet.FetchOnDemand的属性为False

自己取数据集。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: