大家好。我现在工作中遇到了一个问题。业务逻辑层使用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就可以让驱动程序不再自动去做转码工作但是我发现不行。所以特来问下各位同学,有没有人遇到过这个问题,以及如何解决。谢谢
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就可以让驱动程序不再自动去做转码工作但是我发现不行。所以特来问下各位同学,有没有人遇到过这个问题,以及如何解决。谢谢
你前面使用ps和后面使用的sql是否一致?
每次New省不了时间。
但是在SQL Server上为什么直接送查询语句反而省时间,这是因为SQL Server对反复执行的SQL语句会自动使用缓存的执行计划,其他数据库就不一定有这种效果了。
查询字段不多,5、6个字段而已。网络原因不太可能,因为SQLServer的查询分析器也是在我本地运行的如果是网络原因,查询分析器也不会很快有返回结果。PS中的SQL和后面的SQL是一致的。
恩,以前用的MyBatis,对JDBCTemplate不是很了解。我再看看文档吧如果你说数据库对SQL语句有优化的行为,这个可以理解但是,为什么我不使用preparedStatement,而直接用拼接SQL字符串的方式执行的时候,速度非常快呢,和在查询分析器里执行效率差不多都在1秒左右。一般的数据库都会有优化和缓存策略。不只是SQLServer有,但是使用PreparedStatement查询,在参数中出现字符串的时候,查询效率低,却只有SqlServer才有