此问题已经在这里有了答案:
我在应用程序中使用很多SELECT ... FROM ... WHERE ... IN (...)
,并且每次生成一个PreparedStatement
时,例如
public List<String> getUsernames(int[] ids) {
String sql = "SELECT username FROM user WHERE id IN (" + String.join(", ", Collections.nCopies(ids.length, "?") + ")";
try (PreparedStatement ps = conn.prepareStatement(sql)) {
for (int i = 0; i < ids.length; i ++) {
ps.setInt(i + 1, ids[i]);
}
ResultSet rs = ps.executeQuery();
...
}
...
}
每次我呼叫getUsernames
时,由于ID的长度不同,可能会生成不同的PreparedStatement。
我认为数据库引擎每次都会生成一个新的查询计划,对于某些数据库,这可能需要很多Prepared Statement Cache。
有没有办法为可变数量的参数构建一个准备好的语句?
我相信以下查询:
SELECT username FROM user WHERE id IN (1, 2, 3)
SELECT username FROM user WHERE id IN (1, 2, 3, 4, 5, 6)
应该具有相同的查询计划,并且只能被缓存一次。
您可以考虑只维护一个带有固定数量(1024)绑定参数的准备好的语句。然后,只需绑定您实际拥有的值,然后将第一个参数绑定到其他未被使用的占位符即可。