JDBC 驱动程序的预处理语句元数据缓存

下载 JDBC 驱动程序

本文提供有关两项改进驱动程序性能的更改的信息。

预定义语句的 unprepare 批处理

从版本 6.2 开始,实现了性能的改进,最大限度地减少了到 SQL Server 的服务器往返。 此前,对于每个 prepareStatement 查询,还会发送对 unprepare 的调用。 现在,驱动程序会将未执行的查询批处理至阈值 ServerPreparedStatementDiscardThreshold,默认值为 10。

注意

用户可以使用以下方法更改默认值: setServerPreparedStatementDiscardThreshold(int value)

在版本 6.2 之前,驱动程序始终调用 sp_prepexec。 在 6.2 及更高版本中,对于已准备语句的首次执行,驱动程序调用 sp_executesql 以及执行 sp_prepexec 其余语句并为其分配句柄。 有关详细信息,请参阅 PreparedStatement 元数据缓存

从版本 11.2 开始,在初始sp_executesql调用后,驱动程序可以执行或sp_preparesp_prepexec执行额外的调用,具体取决于连接字符串属性中指定的prepareMethod值。 有关详细信息,请参阅设置连接属性

注意

通过使用以下方法将 enablePrepareOnFirstPreparedStatementCall 设置为 true,用户可以将默认行为更改为先前版本的“始终调用 sp_prepexec”:setEnablePrepareOnFirstPreparedStatementCall(boolean value)

此更改引入了新 API 列表,用于对预定义语句进行 unprepare 批处理

SQLServerConnection 取消准备批处理

新方法 说明
int getDiscardedServerPreparedStatementCount() 返回当前未完成的 unprepare 操作数。
void closeUnreferencedPreparedStatementHandles() 对任何未完成的已放弃预定义语句强制执行 unprepare 请求。
boolean getEnablePrepareOnFirstPreparedStatementCall() 返回特定连接实例的行为。 如果为 false,则第一次执行调用 sp_executesql,并且不准备语句。 如果发生第二次执行,则它会调用 sp_preparesp_prepexec,并实际设置预定义的语句句柄。 以后的执行调用 sp_execute。 如果该语句仅执行一次,则此行为无需在预定义语句关闭时使用 sp_unprepare。 可以通过调用 setDefaultEnablePrepareOnFirstPreparedStatementCall() 来更改此选项的默认值。
void setEnablePrepareOnFirstPreparedStatementCall(布尔值) 指定特定连接实例的行为。 如果该值为 false,则第一次执行调用 sp_executesql,并且不准备语句。 如果发生第二次执行,则它会调用 sp_preparesp_prepexec,并实际设置预定义的语句句柄。 以后的执行调用 sp_execute。 如果该语句仅执行一次,则此行为无需在预定义语句关闭时使用 sp_unprepare
int getServerPreparedStatementDiscardThreshold() 返回特定连接实例的行为。 此设置控制在执行调用以清除服务器上未完成的句柄之前,每个连接可以有多少个未完成的放弃操作 (sp_unprepare)。 如果设置 <= 1,则在预定义语句关闭时将立即执行 unprepare 操作。 设置为 > 1 时,这些调用会一起批处理,以避免调用 sp_unprepare 过多的开销。 可以通过调用 getDefaultServerPreparedStatementDiscardThreshold() 来更改此选项的默认值。
void setServerPreparedStatementDiscardThreshold(int value) 指定特定连接实例的行为。 此设置控制在执行调用以清除服务器上未完成的句柄之前,每个连接可以有多少个未完成的放弃操作 (sp_unprepare)。 如果设置 <= 1,则在预定义语句关闭时将立即执行 unprepare 操作。 设置为 > 1 时,这些调用将被批处理在一起,以避免过于频繁调用 sp_unprepare 导致的开销。

SQLServerDataSource unprepare 批处理

新方法 说明
void setEnablePrepareOnFirstPreparedStatementCall(boolean enablePrepareOnFirstPreparedStatementCall) 如果此配置为 false,则预定义语句的第一次执行将调用 sp_executesql,并且不预定义语句。 如果发生第二次执行,它将调用 sp_preparesp_prepexec,并设置一个预备语句句柄。 以后的执行调用 sp_execute。 如果语句仅执行一次,则此行为无需 sp_unprepare 关闭准备的语句。
boolean getEnablePrepareOnFirstPreparedStatementCall() 如果此配置返回 false,则预定义语句的第一次执行将调用 sp_executesql,并且不预定义语句。 如果发生第二次执行,则它会调用 sp_preparesp_prepexec,并实际设置预定义的语句句柄。 以后的执行调用 sp_execute。 如果语句仅执行一次,则这种行为不再需要sp_unprepare关闭准备语句。
void setServerPreparedStatementDiscardThreshold(int serverPreparedStatementDiscardThreshold) 此设置控制在执行调用以清除服务器上未完成的句柄之前,每个连接可以有多少个未完成的放弃操作 (sp_unprepare)。 如果设置 <= 1,则在预定义语句关闭时将立即执行 unprepare 操作。 设置为 > 1 时,这些调用会被批量处理,以避免过于频繁地调用 sp_unprepare 所带来的开销
int getServerPreparedStatementDiscardThreshold() 此设置控制在执行调用以清除服务器上未完成的句柄之前,每个连接可以有多少个未完成的放弃操作 (sp_unprepare)。 如果设置 <= 1,则在预定义语句关闭时将立即执行 unprepare 操作。 设置为 > 1 时,这些调用会一起批处理,以避免调用 sp_unprepare 过于频繁带来的开销。

预定义语句元数据缓存

从版本 6.4 开始,Microsoft SQL Server 的 JDBC 驱动程序支持准备好的语句缓存。 在版本 6.4 之前,如果执行已准备好并存储在缓存中的查询,则再次调用同一查询不需要再次准备。 驱动程序在缓存中查找查询以找到句柄,然后使用该句柄通过 sp_execute 执行查询。 默认情况下,预定义语句元数据缓存处于“禁用”状态。 若要启用它,请对连接对象调用以下方法:

setStatementPoolingCacheSize(int value) //value is the desired cache size (any value bigger than 0) setDisableStatementPooling(boolean value) //false allows the caching to take place

例如:connection.setStatementPoolingCacheSize(10)connection.setDisableStatementPooling(false)

此更改引入了新 API 列表,用于预定义语句的元数据缓存

SQLServerConnection 元数据缓存

新方法 说明
void setDisableStatementPooling(布尔值) 将语句池设置为 true 或 false。
boolean getDisableStatementPooling() 如果禁用了语句池,则返回 true。
void setStatementPoolingCacheSize(int value) 指定此连接的预定义语句缓存的大小。 值 < 1 表示无缓存。
int getStatementPoolingCacheSize() 返回此连接的准备的语句缓存的大小。 值 < 1 表示无缓存。
int getStatementHandleCacheEntryCount() 返回准备的共用语句句柄的当前数目。
boolean isPreparedStatementCachingEnabled() 是否为此连接启用语句池。

SQLServerDataSource 元数据缓存

新方法 说明
void setDisableStatementPooling(boolean disableStatementPooling) 将语句池设置为 true 或 false
boolean getDisableStatementPooling() 如果禁用了语句池,则返回 true。
void setStatementPoolingCacheSize(int statementPoolingCacheSize) 指定此连接的预定义语句缓存的大小。 值 < 1 表示无缓存。
int getStatementPoolingCacheSize() 返回此连接的准备的语句缓存的大小。 值 < 1 表示无缓存。

另请参阅

使用 JDBC 驱动程序Prepared 语句参数性能提高性能和可靠性