命名参数和位置参数之间的性能差异

时间:2015-09-03 15:49:08

标签: java sql hibernate jdbc parameter-passing

我知道与普通Select进行比较,将值直接放入SQL语句中,就像这样:

Statement command = connection.createStatement( "SELECT * FROM person WHERE name = "+ nameVar);

使用JDBC和位置参数执行此操作,如下所示:

String statment= "SELECT * from Users WHERE name=? and pass =?";
sentence = conexion.prepareStatement(consulta);
sentence.setString(1, nameVar);
sentence.setString(2, passVar);

对于一些事情更好,例如避免SQL注入,并且还使用更少的内存(仅用于缓存执行计划一次)和性能(因为一次又一次不执行相同的执行计划)

但是如果你有很多“?”可能很难将参数与变量相关联,这可能会导致错误。

我的问题是,如果执行上述位置参数与执行“命名参数”之间存在差异:

String statment= "SELECT * from Users WHERE name=:nameParam and pass =:passParam";
sentence = conexion.prepareStatement(consulta);
sentence.setString("nameParam", nameVar);
sentence.setString("passParam", passVar);

因为更容易并且可以跳过错误

更新

通过评论似乎只使用JPA / Hibernate可以使用:parameters。那问题仍然存在。使用Hibernate有什么区别吗?

1 个答案:

答案 0 :(得分:1)

正如您所指出的那样,您正在构建PreparedStatement,以便DB可以缓存其执行计划等。因此,当驱动程序实际与DB进行对话时,所有性能提升都来自此。

其他好处在于代码。这是DRY-er(不要重复自己),您可以防止SQL注入攻击,因为您可以验证参数并且它们不能向SQL添加“结构更改”。您可以保留对PreparedStatement对象的引用,因此无需重新创建它,等等。

但是您在两种情况下都这样做,因此主要优点是相同的。在幕后,将参数数组传递给驱动程序以运行准备好的语句。

位置参数很可能只是索引到数组中(取决于驱动程序的实现),而命名参数会维护名称映射关系,并在需要时生成正确的数组。

鉴于SQL语句中的参数数量趋于较小(通常可以用一只手或两只手计数),因此创建数组的速度非常快,与通过网络在网络上运行查询的成本相比可以忽略不计数据库。

因此,恕我直言,请尽可能使用有助于您最好地推理代码的方式。性能差异很小。