【发布时间】:2012-01-22 04:47:11
【问题描述】:
我了解使用 Statement 和 PreparedStatement 之间的主要区别(PreparedStatements 允许传入参数)。但我读到了两者之间的细微差别——即 PreparedStatements 可以比通用语句更快,因为 PreparedStatement SQL 是预编译的。
预编译到底是什么意思,为什么会有所不同?
【问题讨论】:
我了解使用 Statement 和 PreparedStatement 之间的主要区别(PreparedStatements 允许传入参数)。但我读到了两者之间的细微差别——即 PreparedStatements 可以比通用语句更快,因为 PreparedStatement SQL 是预编译的。
预编译到底是什么意思,为什么会有所不同?
【问题讨论】:
准备好的语句执行以下检查:
【讨论】:
编译过程中最重要的部分是查询计划的创建。
查询计划,顾名思义,指示数据库应如何执行查询(例如,要使用哪些索引,要使用的连接类型,例如嵌套循环/散列/合并连接等)。 这可能需要一些时间,因为数据库需要分析有关表的信息,以便很好地猜测什么是最佳的(例如表大小、可用索引、索引的具体程度等)。
虽然准备好的语句可以节省时间,但您必须小心,因为它们有时会使您的程序变慢。为什么?因为不提供 where 子句值作为编译的一部分,数据库必须猜测您将提供的值,并且它可能会选择导致您的查询计划不理想的值。
这对于范围查询可能最为明显。例如,假设您创建了一个带有最小和最大日期作为参数的准备好的语句。您将使用此查询来检索几天的交易。鉴于日期范围较小,如果数据库使用日期非聚集索引,则此查询的执行效率可能最高。
但是,由于数据库不知道您将提供哪些参数,因此数据库可能会针对更大的日期范围(例如一年或更长时间)进行优化,这对于使用表扫描执行可能是最有效的。在这种情况下,使用准备好的语句会减慢您的程序速度(除非您向数据库提示要优化哪些参数或明确指出要使用哪些索引)。
当然,如果您在准备好的语句中提供的参数将指向单个记录(例如表上的唯一键),那么数据库在创建查询计划时确实不会出错。
我想我想强调这里有利有弊。 PreparedStatements 在某些情况下可能会更快,但您必须小心。
【讨论】: