PreparedStatement 用问号传参引发查询(SQLServer )数据慢的解决方案

这个坑比较恶心,一般数据小的时候不容易发现,如果你用SqlServer可以参考看看

JDBC使用PreparedStatement 的问号传参方式默认会不走索引,导致查询非常慢,但查询分析器直接查就很快,貌似是传参的编码引起的:

确定是以Unicode还是以数据库的默认字符编码方式将字符串参数发送到SQL Server数据库。这会严重影响SQL Server 2000的性能,因为它不会自动转换类型(如7.0所示),这意味着如果索引列是Unicode并且字符串是使用默认字符编码提交的(或以其他方式)SQLServer将执行索引扫描而不是索引查找。对于Sybase,确定在服务器的字符集中不能编码的字符串是否作为unicode字符串发送。编码逻辑的性能受到影响,因此如果unitext或univarchar数据类型未使用或者charset为utf-8,则将此选项设置为false

解决方法:在jdbc-url上加上 ;sendStringParametersAsUnicode=false

jdbc:sqlserver://127.0.0.1:1433;DatabaseName=test;sendStringParametersAsUnicode=false

也可以用传参的方式加上

Class.forName(DRIVER_CLASS_NAME);
Properties info = new Properties();
info.put("user", USERNAME);
info.put("password", PASSWORD);
info.put("sendStringParametersAsUnicode", "false");
conn = DriverManager.getConnection(URL, info);

以上是最简单的解决方案,看网上也有说改变字段类型,varchar -> nvarchar ,没试过,不懂是否有效

官方文档介绍:

SendStringParametersAsUnicode={true | false}. Determines whether string parameters are sent to the SQL Server database in Unicode or in the default character encoding of the database. True means that string parameters are sent to SQL Server in Unicode. False means that they are sent in the default encoding, which can improve performance because the server does not need to convert Unicode characters to the default encoding. You should, however, use default encoding only if the parameter string data that you specify is consistent with the default encoding of the database. 
The default is true. 

 

转载于:https://my.oschina.net/zwtlong/blog/1789397

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 中可以使用 JDBC (Java Database Connectivity) 来连接 SQL Server 数据库并执行 SQL 语句。下面是一个简单的示例代码,演示如何查询和更新 SQL Server 数据库中的数据: ```java import java.sql.*; public class SQLServerExample { public static void main(String[] args) { String url = "jdbc:sqlserver://localhost:1433;databaseName=mydatabase"; String user = "myusername"; String password = "mypassword"; try { Connection conn = DriverManager.getConnection(url, user, password); // 查询数据 Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM mytable"); while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); System.out.println("id: " + id + ", name: " + name); } // 更新数据 PreparedStatement pstmt = conn.prepareStatement("UPDATE mytable SET name = ? WHERE id = ?"); pstmt.setString(1, "newname"); pstmt.setInt(2, 1); pstmt.executeUpdate(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } ``` 在上面的代码中,`url` 是连接字符串,其中 `localhost` 是 SQL Server 的主机名,`1433` 是 SQL Server 的默认端口号,`mydatabase` 是要连接的数据库名称,`user` 和 `password` 是登录 SQL Server 的用户名和密码。你可以根据实际情况修改这些值。 在查询数据时,首先创建一个 `Statement` 对象,然后执行查询语句,并使用 `ResultSet` 对象遍历结果集。在更新数据时,首先创建一个 `PreparedStatement` 对象,然后使用 `setXXX` 方法设置参数值,最后执行更新语句。 注意,在使用 JDBC 连接 SQL Server 数据库时,需要先下载并安装 Microsoft JDBC Driver for SQL Server。你可以在 Microsoft 官网上下载并安装这个驱动程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值