PreparedStatement.setString() 組裝參數時極慢JDBC 驅動預設 SendStringParametersAsUnicode=true,將字串參數傳為 NVARCHAR (Unicode)。資料表欄位為 VARCHAR (非 Unicode),導致隱含轉換,使索引無法求用 (Index Scan 取代 Seek)。
setString 參數化 → 慢 (索引 Scan,隱含 CONVERT_IMPLICIT)
jdbc:sqlserver://host:1433;DatabaseName=MyDB;SendStringParametersAsUnicode=false
PreparedStatement ps = conn.prepareStatement(sql);
ps.setObject(1, paramValue, java.sql.Types.VARCHAR); // 強制 VARCHAR
| 設定 | 參數型別 | 欄位型別 | 執行計畫 | 相對效能 |
|---|---|---|---|---|
| SendStringParametersAsUnicode=true (預設) | NVARCHAR | VARCHAR | Index Scan + CONVERT_IMPLICIT | 極慢 (100x+) |
| SendStringParametersAsUnicode=false | VARCHAR | VARCHAR | Index Seek | 正常 |
| SendStringParametersAsUnicode=true | NVARCHAR | NVARCHAR | Index Seek | 正常 |
SendStringParametersAsUnicode=falsesys.dm_exec_query_stats 找出 CONVERT_IMPLICIT 計畫「SQL Server 客戶端查詢正常,程式組裝 SQL 慢 → 檢查參數資料型別是否導致隱含轉換破壞索引」