如果我不在预准备语句中使用绑定变量,性能是否会降低?
考虑下面的示例:
String selectSQL = "SELECT USER_ID, USERNAME FROM DBUSER WHERE USER_ID = '101'";
PreparedStatement preparedStatement = dbConnection.prepareStatement(selectSQL);我知道低于1是更可取的。它可以防止sql注入
String selectSQL = "SELECT USER_ID, USERNAME FROM DBUSER WHERE USER_ID = ?";问这个问题是因为我的一个项目在所有查询中都有硬编码的字符串文字,即使他们使用的是准备好的语句。
发布于 2016-07-21 17:12:29
准备好的语句只意味着你“准备”了语句。这意味着您将其发送到数据库,并让数据库已经解析/编译该语句。这对于经常执行的语句很有用。
参数化语句通常会执行多次,因此它们有时会与准备好的语句相关联(您只需发送这些值,服务器就会有一个已经编译好的语句准备好执行查询)。
但是,即使是经常执行的“静态”语句,您也可以从准备语句中受益(特别是对于“复杂”语句)。使用的另一种技术是在存储过程中实现查询。这样,查询就已经被编译了,服务器只需要在您运行它时编译存储过程调用。
它只有在你不取消准备耐力的情况下才会起作用(例如,当关闭连接时)。因此,您可能需要一个池和一个预置语句缓存,以避免预置语句请求使服务器溢出(预置语句需要服务器端的资源)
参数化查询还用于防止sql注入(因为它基于数据类型而不是字符串)。然而,这与预准备语句的好处是正交的。(注意,您的两个查询都不会暴露给sql注入)
发布于 2016-07-21 18:13:00
使用参数是否更有效主要取决于您的用例。当您监控准备和执行语句所花费的时间时,您会注意到,准备语句有时会比实际执行的成本高得多,因此这取决于您是否可以节省准备时间。
在这样的场景中,您将始终获胜:
PreparedStatement stmt = dbConnection.prepareStatement(...);
stmt.setInt(1, x);
stmt.executeQuery();
...
stmt.setInt(1, y);
stmt.executeQuery();
...因为你节省了准备时间。这是独立于DBMS的。
一些DBMS做一些服务器端缓存。他们做什么和如何做是高度供应商的,甚至是版本特定的。然而,我们了解到,在Oracle-DBMS中,经常使用的参数化语句在这种情况下有时会获得相当大的速度:
PreparedStatement stmt = dbConnection.prepareStatement(...);
stmt.setInt(1, x);
stmt.executeQuery();
...
PreparedStatement stmt2 = dbConnection.prepareStatement(...);
stmt2.setInt(1, y);
stmt2.executeQuery();
...在这里,服务器能够识别出两个语句在本质上是相同的,并且第二个语句的准备时间大大减少。这不适用于固定字符串语句,因为服务器无法确定它们是相同的。
我不认为,你会发现,使用参数化语句比固定字符串语句慢得多,但在很多情况下,情况正好相反。
https://stackoverflow.com/questions/38499704
复制相似问题