为什么 JDBC 驱动程序将准备好的语句保持在连接级别?
Why are prepared statements kept at a connection level by the JDBC drivers?
我不是想问他们到底做了什么,而是问他们为什么要这样实现。如果准备好的语句完全由数据库处理,它是否可用于所有连接?但似乎大部分是由驱动程序针对连接处理的,我无法理解其背后的原因。
关于 Postgres 的问题。
如果语句已准备好,它会被发送到数据库,数据库解析和分析该语句并发回某种句柄 (=id),以后可以根据需要经常使用该句柄来执行该语句。因此,与其将整个语句一遍又一遍地发送到数据库,不如将句柄和可能的查询参数传输到数据库。
如您所知,准备好的语句绑定到当前数据库连接,因此当连接关闭时,语句将从数据库缓存中删除。
我不知道您认为对所有连接进行此类准备好的语句 public 会有什么好处。如果您真的想要 public 语句存储在服务器上,请改用 stored procedures or SQL views!
准备好的语句绑定到连接有几个原因(从数据库的JDBC 和的角度来看),它们归结为"simplicity":
资源管理:通过将语句与连接相关联,可以很容易地清除任何未明确关闭的语句:如果连接关闭,任何打开的语句也会关闭。
在大多数数据库系统中,语句句柄也是游标句柄,这意味着它一次只能被一个连接使用,将它绑定到一个连接上更有意义。
语句生命周期(或至少是执行生命周期,参见 2)与事务关联,事务也绑定到连接。某些数据库允许一个连接上有多个活动事务,但 JDBC 假定每个连接一个。
在大多数数据库系统中,语句的准备取决于准备它的事务的元数据 (DDL) 可见性,拥有全局池会使这变得复杂(例如允许哪个连接 use/see 哪个语句)。
用户权利和特权有时会在准备时进行部分检查。全局池会使这个复杂化(参见 4)。
可能还有一些我现在忘记的其他原因。我认为最重要的是第一个(如果有一个全局池,其他的将以不同的方式实现)。
这不会阻止数据库系统也有一个全球准备好的语句池(或至少:准备元数据,如访问路径、执行计划等)。然而,从用户的角度来看,准备好的语句的实例仍然绑定到一个连接。
我不是想问他们到底做了什么,而是问他们为什么要这样实现。如果准备好的语句完全由数据库处理,它是否可用于所有连接?但似乎大部分是由驱动程序针对连接处理的,我无法理解其背后的原因。
关于 Postgres 的问题。
如果语句已准备好,它会被发送到数据库,数据库解析和分析该语句并发回某种句柄 (=id),以后可以根据需要经常使用该句柄来执行该语句。因此,与其将整个语句一遍又一遍地发送到数据库,不如将句柄和可能的查询参数传输到数据库。
如您所知,准备好的语句绑定到当前数据库连接,因此当连接关闭时,语句将从数据库缓存中删除。
我不知道您认为对所有连接进行此类准备好的语句 public 会有什么好处。如果您真的想要 public 语句存储在服务器上,请改用 stored procedures or SQL views!
准备好的语句绑定到连接有几个原因(从数据库的JDBC 和的角度来看),它们归结为"simplicity":
资源管理:通过将语句与连接相关联,可以很容易地清除任何未明确关闭的语句:如果连接关闭,任何打开的语句也会关闭。
在大多数数据库系统中,语句句柄也是游标句柄,这意味着它一次只能被一个连接使用,将它绑定到一个连接上更有意义。
语句生命周期(或至少是执行生命周期,参见 2)与事务关联,事务也绑定到连接。某些数据库允许一个连接上有多个活动事务,但 JDBC 假定每个连接一个。
在大多数数据库系统中,语句的准备取决于准备它的事务的元数据 (DDL) 可见性,拥有全局池会使这变得复杂(例如允许哪个连接 use/see 哪个语句)。
用户权利和特权有时会在准备时进行部分检查。全局池会使这个复杂化(参见 4)。
可能还有一些我现在忘记的其他原因。我认为最重要的是第一个(如果有一个全局池,其他的将以不同的方式实现)。
这不会阻止数据库系统也有一个全球准备好的语句池(或至少:准备元数据,如访问路径、执行计划等)。然而,从用户的角度来看,准备好的语句的实例仍然绑定到一个连接。