【问题标题】:Statement vs Prepared Statement in terms of Precompilation预编译方面的声明与准备好的声明
【发布时间】:2012-01-22 04:47:11
【问题描述】:

我了解使用 Statement 和 PreparedStatement 之间的主要区别(PreparedStatements 允许传入参数)。但我读到了两者之间的细微差别——即 PreparedStatements 可以比通用语句更快,因为 PreparedStatement SQL 是预编译的。

预编译到底是什么意思,为什么会有所不同?

【问题讨论】:

标签: sql jdbc


【解决方案1】:

准备好的语句执行以下检查:

  • 确保表和列存在
  • 确保参数类型与其列匹配
  • 解析 SQL 以确保语法正确
  • 编译并缓存已编译的 SQL,以便无需重复这些步骤即可重新执行它

【讨论】:

  • 检查表和列是否存在,验证语法,验证访问,准备执行计划:数据库服务器为每条语句执行此操作,无论是否准备好。像 Oracle 这样的服务器也会根据收到的语句字符串的哈希值缓存语句(准备或未准备)。一旦这项工作完成,并且 db 服务器已经“准备”了一个准备就绪的内存区域,那么 jdbc 驱动程序就可以绑定参数并使用这个服务器对象。然后重新绑定新参数并再次使用,而无需重新准备语句。如果驱动程序以这种方式实现它。
【解决方案2】:

编译过程中最重要的部分是查询计划的创建。

查询计划,顾名思义,指示数据库应如何执行查询(例如,要使用哪些索引,要使用的连接类型,例如嵌套循环/散列/合并连接等)。 这可能需要一些时间,因为数据库需要分析有关表的信息,以便很好地猜测什么是最佳的(例如表大小、可用索引、索引的具体程度等)。

虽然准备好的语句可以节省时间,但您必须小心,因为它们有时会使您的程序变慢。为什么?因为不提供 where 子句值作为编译的一部分,数据库必须猜测您将提供的值,并且它可能会选择导致您的查询计划不理想的值。

这对于范围查询可能最为明显。例如,假设您创建了一个带有最小和最大日期作为参数的准备好的语句。您将使用此查询来检索几天的交易。鉴于日期范围较小,如果数据库使用日期非聚集索引,则此查询的执行效率可能最高。

但是,由于数据库不知道您将提供哪些参数,因此数据库可能会针对更大的日期范围(例如一年或更长时间)进行优化,这对于使用表扫描执行可能是最有效的。在这种情况下,使用准备好的语句会减慢您的程序速度(除非您向数据库提示要优化哪些参数或明确指出要使用哪些索引)。

当然,如果您在准备好的语句中提供的参数将指向单个记录(例如表上的唯一键),那么数据库在创建查询计划时确实不会出错。

我想我想强调这里有利有弊。 PreparedStatements 在某些情况下可能会更快,但您必须小心。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-04
    • 2013-10-11
    • 1970-01-01
    • 2014-01-20
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多