SQL预编译语句

时间:2013-11-06 16:17:41

标签: java oracle jdbc spring-jdbc

我有这样的SQL查询。

select * from table where owner='b' value=? and chanel='5'

我将始终只使用所有者b和chanel 5进行搜索,将其保留为如下所示的占位符是否有意义。

select * from table where owner=? and value=? and chanel=?

它是否会提高性能还是有任何优势?

亚当。

4 个答案:

答案 0 :(得分:1)

Oracle可以在第一个问题中使用额外信息,因此可以更好地优化它。

它是否会产生明显的差异?取决于您的数据和索引。 在大多数情况下,没有明显的差异,或者第一个会稍快一些。

在某些特定情况下(特别是如果统计数据不是最新的),第一种形式可能会表现更差。 (例如,见Oracle SQL: additional restriction causes performance issues

答案 1 :(得分:0)

我认为性能优势可以忽略不计,但使用占位符的安全性好处可能很大。真正的绩效表现将来自重新使用PreparedStatement(而不是为每个查询创建一个)。

考虑“b”和“5”来自用户的情况(例如,Web应用程序中的请求参数)。如果使用字符串连接创建了字符串,则会将应用程序打开到SQL Injection次攻击。使用占位符可以保护您的应用免受SQL注入攻击。

这幅漫画很好地解释了这个问题:http://xkcd.com/327/

答案 2 :(得分:0)

准备好的语句确实可以提高性能,但前提是您要在项目中多次使用相同的查询。

但它也带来了诸如避免SQL注入等优点,并允许您将特定于数据库的所有内容集中到数据库管理类中。如果从Oracle更改为其他内容,您只需更改代码中的一个类。

这个相同的数据库管理类可以在程序启动时初始化所有准备好的语句,这样它们就可以在以后需要时准备好,从而获得性能。

Here is an exemple使用此模型的开源项目。这是C ++,但可能会给你一个想法。

答案 3 :(得分:0)

使用文字的一些好处:

  1. 避免奇怪的优化程序限制和错误。这是使用文字的主要原因。 Oracle可以使用adaptive cursor sharing为同一SQL语句构建不同的计划,具体取决于绑定变量的值。构建基于绑定值而更改的计划很困难,并且存在许多限制和错误。例如,它仅支持最多14个绑定变量,并且不支持LIKE谓词。如果你的一个非真正绑定变量为真正的绑定变量禁用了这个特性,它可能会导致问题。
  2. 语句更易于阅读。特别是对于从V $ SQL查看语句的DBA。将绑定信息添加到查询是额外的工作,有时这些数据不可用。它可以使解释计划更容易生成和阅读。例如,使用文字说明解释计划可能会显示正在使用的确切分区。使用绑定变量时,它可能只显示KEY,这不会明确哪个
  3. 小的性能提升。我不确切知道优化器是如何工作的,但可以肯定的是它必须存储绑定变量并查找它们以比较用于现有计划的值。避免这些查找应该有所帮助,尽管差异可能非常小。
  4. 文字的明显缺点,你可能已经考虑过了:

    1. 如果您只是直接从用户那里插入数据,那么可能会注入SQL。
    2. 如果您想稍后更改代码,则不够灵活。