各位朋友好,和大家探讨一个问题。我对SQL执行过程的理解比较肤浅,对于一个select操作,我的理解是:
客户端发送一个select sql语句给服务器端,服务器端进行检查、执行、生成结果集,然后返回给客户端一个结果集的句柄(或者游标之类),供客户端进行后面自己所需要的操作。在这个过程中,处理压力都在服务器端,客户端除了发送一个sql语句,接收返回执行状态结果和结果集句柄外,不会有什么压力,客户端机器的cpu、内存、网络等都会很空闲。但是我现在遇到一个问题,对我这个理解产生很大挑战。我在和一个客户讨论数据库测试方案时(针对多种不同的数据库),期中有一个测试用例,是一个简单的select操作(select * from table1),结果集很大,会有几千万记录。客户的疑惑是,这样的测试用例,会对发送这个sql的客户端压力很大(说主要是网络方面),执行该语句后,客户端会一条一条的返回结果集数据。因为对方的技术也很好,所以我现在很疑惑。这对我以前对sql的理解完全不一样。我的问题是:当我执行一个会产生很大结果集的select * from table1这样的操作时,对发送sql的客户端,是否会有这么大的压力?或者不同的数据库厂商策略不同?对这个问题很疑惑,向大家请教,谢谢大家了!

解决方案 »

  1.   

    补充一些内容:我的发送sql的客户端,是用jdbc写的一段简单的代码,只是发送一个select过去,不进行其他任何操作。不知道是否是通过在程序代码中进行一些设置,可以对客户端的压力进行控制?我在网上还看到一位朋友写的,当一个select执行到最后一步时的情景:
    “当语句执行完成之后,查询到的数据还是在服务器进程中,还没有被传送到客户端的用户进程。所以,在服务器端的进程中,有一个专门负责数据提取的一段代码。他的作用就是把查询到的数据结果返回给用户端进程,从而完成整个查询动作”这个‘专门负责数据提取的一段代码’是一个守候进程吗?客户端如果不发出下面的请求,不会主动返回什么数据?
      

  2.   

    客户端当然有压力了。除了网络方面的资源消耗,你要接收这么大数据,如果还需要显示。这些数据肯定要占用资源。就好比你打开本地一个很大的文件一样。当然会对你的客户端造成压力。
    而如果你执行的不是select显示的。而只是一个大数据量处理的问题。那发送SQL后就在服务端处理了。由于你执行的是select所以对客户端是有影响的。
      

  3.   

    谢谢yangqm22!数据不需要显示出来。“由于你执行的是select所以对客户端是有影响的。”,结论是什么呢?对不起,我没有太理解你表达的意思
      

  4.   

    select是获得结果集,不管你是显示还是保存到某个结果集里面这部分都是客户端进行。
      

  5.   

    可以看一下这篇文章:
    从客户端提升SQL Server数据库性能
      

  6.   

    select的步骤就是发送、解析、执行、数据提取这些都在服务端,然后返回结果集时就要消耗网络资源和客户端资源(接收或者显示)。所以会对客户端造成影响。
      

  7.   

    第一个是网络传输压力,一般情况下,局域网的传输速率是4M每秒,假设一行数据的平均长度是0.5k,那么1000w条记录大概要传输差不多5G的数据,即使你使用光纤也有点受不了第二个是客户端的CPU,内存和虚拟内存的压力,这么多数据传输过来,你总要有东西来储存和处理他们,不管数据库连接驱动程序设计得多么美妙,它总也不可能逃出硬件限制的框架。
      

  8.   

    谢谢各位朋友的解答,现在来看,select会把结果集传回给客户端,而不是我之前理解的只是返回一个可以操作结果集的句柄。那么对于我现在的那个测试用例:select操作(select * from table1,结果集为1千万条记录)。这个测试用例就属于设计不合理的了?因为并不光是在测试数据库,而是会对测试的客户端也造成很大压力(比如网络传输,变成了测试网络了)。那么大家认为应该如何调整这个测试用例呢?其实我现在还是挺纠结的,select竟然会把整个结果集返回给客户端。多年形成的想法不好改变,也是自己学习不深
      

  9.   

    select count(*) from table1  
      

  10.   

    谢谢zsh0809
    把selcet * 改为select count(*),在数据库端,还会做那么多的运算和临时表的构建吗?我是担心起不到测试的效果
      

  11.   

    客户端没有任何的封装和处理,只是发出一条select语句
      

  12.   

    刚才和一个对数据库比较熟悉的同事聊天,说到这个问题,他的看法和我最初的类似,也是认为服务器端会保存检索结果集,除非客户端有get的要求,否则不会主动发送结果到客户端去。
    现在彻底糊涂了
      

  13.   

    如果把
    select * from table1
    改为
    select count(*) from (select * from table1)
    后者是否就不会向客户端返回结果集了呢?
      

  14.   


    试试就知道了,SQLPLUS里你用SELECT * 不加限制的话是一次返回所有的数据,而我们常用的开发工具,如PL SQL DEV,TOAD都是先返回部分数据,即是加了行数限制,类似于分页,当然,JDBC驱动的优化参考http://hi.baidu.com/lovemywolf/blog/item/b2e3a912e22e67cfc2fd78a3.html
      

  15.   

    我记得有个oracle很在行的同事也这样说过,除非客户端有要求,不然是不会返回给客户端看的;