怎样提高SQLServer的查询和结算的速度,在1000万条纪录以上

我在处理话单的过程中,我用Delphi编写的程序,使用ADOQuery,查询话单时的 SQL 为
select * from 话单 where 挂机时间 between '2002-01-01' and '2002-02-01' ,这一段时间的话单数量为90万条左右,我查询这一段的话单时,机器老是会出现内存溢出的情况,结算着一个月的数据时,大约二十分钟左右,使用什么方式会增加查询和结算的速度.
---------------------------------------------------------------

先建立索引增加查询和结算的速度。
至于显示,可分段查询,分段显示。先判断记录数,如大于50000(如900000),你可以根据主索引分成n段,如1-50000,50001-100000,...

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

我不知道你是否知道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个字节。9001024100=90MB!如果你的应用程序与服务器不再同一台机器,90M的数据仅网络传送时间就非常可观了。所以建议使用多次小批量的查询来代替一次查询所有记录的做法,你可以每次只查一天的纪录,查询n次来返回一个月的纪录。实践证明这种查询模式比一次查询所有记录要快(我的实际经验)。
---------------------------------------------------------------

能够分细的就尽量细。。
例如DELPHI用个循环查
where 挂机时间='2002-1-1'

where 挂机时间='2002-1-31'
那样内存使用量就是原来的1/30之一啦。。
在循环外层继续可以套循环啊。例如可以根据客户的分类。
那么每次查询使用的内存更少了。

这样分开来做,SQL SERVER上话的时间更多。
不过在那时间段内机子的附和会少点的。

Published At
Categories with 数据库类
Tagged with
comments powered by Disqus