大家好。我现在工作中遇到了一个问题。业务逻辑层使用Spring,数据层是Spring提供的JDBCTemplate在执行SQL语句的时候,会用到类似如下的方式执行代码
this.getJdbcTemplate().query(new PreparedStatementCreator(){
   /*
    *这里的方法主要是实现prepareStatement方法
    *根据SQL语句里的?,把参数设置到ps对象上
    *然后返回ps对象
    */
}, new RowMapper(){   //这里的方法就不写了});但是我发现一个问题。如果我用上述方式执行SQL语句,一次查询需要20多秒返回。关于数据量和数据结构我就不多解释了,因为已经发现和这些无关了。如果在SqlServer的查询分析器里执行这条SQL语句,只需要不到1秒的时间。起初我以为是本地的链接受限。后来发现,当我不使用preparedStatement执行SQL语句的时候,比如,我在代码里,把参数以字符串的形式拼在SQL语句的String对象里,直接使用 
this.getJdbcTemplate().query(sql, new RowMapper(){});这样的方法,执行SQL返回数据只需要不到1.5秒的时间。在网上查阅了一些资料,貌似是使用preparedStatement的时候,如果SQL语句参数里有字符串类型驱动程序会执行一些操作,进行转码或者类似的一些工作。查询效率低,就是这个原因。有人说,在配置数据源的时候,url参数里,加一个 sendStringParamtersAsUnicode=false就可以让驱动程序不再自动去做转码工作但是我发现不行。所以特来问下各位同学,有没有人遇到过这个问题,以及如何解决。谢谢

解决方案 »

  1.   

    是否是查询字段过多?导致,网络数据量大?
    你前面使用ps和后面使用的sql是否一致?
      

  2.   

    PreparedStatement应该是准备一次,多次运用才省时间的吧。
    每次New省不了时间。
    但是在SQL Server上为什么直接送查询语句反而省时间,这是因为SQL Server对反复执行的SQL语句会自动使用缓存的执行计划,其他数据库就不一定有这种效果了。
      

  3.   


    查询字段不多,5、6个字段而已。网络原因不太可能,因为SQLServer的查询分析器也是在我本地运行的如果是网络原因,查询分析器也不会很快有返回结果。PS中的SQL和后面的SQL是一致的。
      

  4.   


    恩,以前用的MyBatis,对JDBCTemplate不是很了解。我再看看文档吧如果你说数据库对SQL语句有优化的行为,这个可以理解但是,为什么我不使用preparedStatement,而直接用拼接SQL字符串的方式执行的时候,速度非常快呢,和在查询分析器里执行效率差不多都在1秒左右。一般的数据库都会有优化和缓存策略。不只是SQLServer有,但是使用PreparedStatement查询,在参数中出现字符串的时候,查询效率低,却只有SqlServer才有
      

  5.   

    问题知道原因了,但是解决的不太好原因出在PreparedStatement上,当使用这个的时候,查询就是慢因为涉及到参数赋值神马的然后,就是配置数据源的时候执行一下 sendStringParameterAsUnicode=false