select查询大量数据时的内存使用问题
这个问题之前一直没有想过。如果要返回20w数据,是直接把这些数据放到内存里后然后通过tcp返回给客户端,还是说会分批返回?如果是分批的话,有什么参数设置吗?
------解决方案--------------------分批不也要占住内存嘛,不然数据从哪里来?首先除了一些初级报表之外,一般很少需要直接返回20万数据,如果这样,那恐怕都要用分页技术。其实从执行计划来看,20万也就几十MB左右,如果展现的快,性能上问题不大,我反而担心你前端缓存的问题
------解决方案--------------------首次查询时,数据从磁盘读取到内存缓冲区中,如何传递给客户端,得看启用了什么协议.
通常是tcp/ip,如果服务器客户端在同一台机器,则直接共享内存即可.
------解决方案--------------------20w的数据还不是很大,发送的时候是一部分一部分发送到客户端的,因为sql server把数据封装到网络数据包中,而数据包的大小一般就是4k-8k左右,所以肯定需要发送多次。
我觉得如果有大量用户都要看这些数据,尅考虑把结果集缓存在你的web端,这样的话,至少对网络的压力就下多了,只不过,得有一种机制控制,当数据有更新、删除、插入后,重新从数据库中再次加载数据。
当然,如果你的表中的数据经常更新,那么这个方案也不太合适,因为为了保证数据的正确性,而当更新等dml操作比较多,经常性的需要刷新缓存的结果集,那么意义就不大了,还不如有需要的时候去查询。
不过这样,还是可以考虑读写分离,通过用2台服务器,一台专做更新,一个专门做查询,把数据修改同步到读的服务器上。
另外,sql server现在还不支持结果集的缓存,在oracle里支持,把运行完的结果集直接缓存在内存中,如果下载的语句相同,那么直接取结果就可以了。当然啦,这个缓存也是基于这个结果集是要正确的,如果这个结果集的数据,刚被更新过,那么还是得重新在select一遍。
------解决方案--------------------
是的,但还是得运行这个语句,虽然是从内存中取数,但是还是得消耗,编译执行等开销。