Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在IN子句中对大型列表使用bind变量时出现性能问题_Sql_Sybase_Spring Jdbc_Jdbctemplate - Fatal编程技术网

Sql 在IN子句中对大型列表使用bind变量时出现性能问题

Sql 在IN子句中对大型列表使用bind变量时出现性能问题,sql,sybase,spring-jdbc,jdbctemplate,Sql,Sybase,Spring Jdbc,Jdbctemplate,我正在使用Sybase,有一些代码如下所示: String[] ids = ... an array containing 80-90k strings, which is retrieved from another table and varies. for (String id : ids) { // wrap every id with single-quotes } String idsAsString = String.join(",", ids); String que

我正在使用Sybase,有一些代码如下所示:

String[] ids = ... an array containing 80-90k strings, which is retrieved from another table and varies.
for (String id : ids) {
    // wrap every id with single-quotes 
}
String idsAsString = String.join(",", ids); 
String query = String.format("select * from someTable where idName in (%s)", idsAsString);
getNamedParameterJDBCTemplate().query(query, resultSetExtractor ->{
    // do stuff with results
});
我已经计算了到达ResultsTextRactor的内部主体所需的时间,但从未超过4秒

但是为了确保代码的安全,我尝试了绑定变量路径。因此,该代码如下所示:

String[] ids = ... an array containing 80-90k strings, which is retrieved from another table and varies.
String query = "select * from someTable where idName in (:ids)";
Map<String, Object> params = new HashMap<>();
params.put("ids", Arrays.asList(ids));
getNamedParameterJDBCTemplate().query(query, params, resultSetExtractor ->{
    // do stuff with results 
});
我还有其他一些代码,其中我将大小为1-10的数组作为绑定变量传递,并注意到这些查询从瞬时到长达10秒


我很惊讶绑定变量的方式完全不同,更不用说完全不同了。有人能解释一下这是怎么回事吗?与通过JDBC发送格式化字符串不同的是,bind变量在后台做了一些不同的事情吗?有没有其他方法可以在不大幅降低性能的情况下保护我的代码?

您应该通过showplan/查询计划验证数据库端实际发生的情况,但使用“in”子句最多只能对“in”子句中的每个值进行一次索引搜索,因此10个值进行10次搜索,80k搜索完成了其中的80k个,因此速度大大减慢。Oracle实际上禁止在“in”子句中放入超过1000个值,而Sybase没有那么严格,这并不意味着它是一个好主意。通过以这种方式放置大量值,您可能会在数据库中遇到堆栈和其他问题。我见过这样的查询会导致生产数据库实例出现堆栈故障

最好创建一个临时表,将80k值加载到其中,并使用前面使用in子句搜索的列在临时表和主表之间进行内部联接

21-10-2019 14:04:01 DEBUG DefaultConnectionTester:126 - Testing a Connection in response to an Exception:
com.sybase.jdbc4.jdbc.SybSQLException: The token datastream length was not correct. This is an internal protocol error.