预编译方面的语句与准备语句

时间:2012-01-22 04:47:11

标签: sql jdbc

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

预编译究竟是什么意思,为什么会产生影响?

2 个答案:

答案 0 :(得分:8)

准备好的陈述执行以下检查:

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

答案 1 :(得分:4)

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

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

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

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

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

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

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