关于预编译,Statement和Prepared Statement之间有何区别?

5

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

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


关于预编译的好细节: https://dev59.com/rW035IYBdhLWcg3wT-NB - Awan
2个回答

9

预编译语句执行以下检查:

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

2
检查表和列的存在性,验证语法,验证访问权限,准备执行计划:数据库服务器会为每个语句(已准备或未准备)执行这些操作。像Oracle这样的服务器还会基于接收到的语句字符串的哈希值缓存语句(已准备或未准备)。一旦完成这项工作,数据库服务器就会“准备”一个内存区域以便随时使用,然后jdbc驱动程序可以绑定参数并使用此服务器对象。如果驱动程序是这样实现的话,那么可以重新绑定新参数并再次重复使用而无需重新准备语句。 - Glenn

4
编译过程中最重要的部分是创建查询计划。查询计划,顾名思义,指示数据库应如何执行查询(例如使用哪些索引,使用哪种连接类型,如嵌套循环/哈希/合并连接等)。这可能需要时间,因为数据库需要分析表上的信息以猜测最佳操作方式(例如表大小、可用索引、索引的特定性等)。
虽然预处理语句可以节省时间,但必须小心,因为它们有时会使程序变慢。为什么?因为通过不将where子句值作为编译的一部分提供,数据库必须猜测您要提供的值,并且它可能选择导致您的查询计划次优的值。
这可能在范围查询中最为明显。例如,假设您创建了一个包含最小和最大日期参数的预处理语句。您将使用此查询来检索几天的交易记录。鉴于较小的日期范围,如果数据库使用日期非聚集索引,则此查询可能是执行最有效的查询。
但是,由于数据库不知道您将提供哪些参数,因此数据库可能会针对更大的日期范围进行优化(例如一年或更长时间),这可能是使用表扫描执行的最有效方法。在这种情况下,使用预处理语句会减慢程序的速度(除非您向数据库提供有关要优化哪些参数的提示或明确指示使用哪些索引)。
当然,如果在预处理语句中,您将提供的参数将指向单个记录(例如表上的唯一键),则数据库实际上无法在创建查询计划时出错。
我想我正在强调这里的利弊。在某些情况下,预处理语句可能更快,但必须小心。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接