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

下载 JDBC 驱动程序

本文介绍了为提高驱动程序的性能而实现的两个更改。

预定义语句的 unprepare 批处理

自 6.1.6 预览版开始,通过将服务器往返行程最小化到 SQL Server 来实现性能改进。 此前,对于每个 prepareStatement 查询,还会发送对 unprepare 的调用。 现在,驱动程序将批处理 unprepare 查询,直到达到阈值“ServerPreparedStatementDiscardThreshold”,其默认值为 10。

注意

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

6\.1.6 预览版中引入的另一个更改是在此版本之前,驱动程序将始终调用 sp_prepexec。 现在,在第一次执行预定义语句时,驱动程序将调用 sp_executesql,对于其他情况,则执行 sp_prepexec 并为其分配一个句柄。 此处提供了更多详细信息。

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

注意

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

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

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

SQLServerDataSource

新方法 说明
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 操作。 如果设置为 {@literal >} 1,则会对这些调用进行批处理,以避免过于频繁地调用 sp_unprepare 的开销
int getServerPreparedStatementDiscardThreshold() 此设置控制在执行调用以清除服务器上未完成的句柄之前,每个连接可以有多少个未完成的放弃操作 (sp_unprepare)。 如果设置 <= 1,则在预定义语句关闭时将立即执行 unprepare 操作。 如果设置为 {@literal >} 1,则会对这些调用进行批处理,以避免过于频繁地调用 sp_unprepare 的开销。

预定义语句元数据缓存

从 6.3.0 预览版开始,Microsoft JDBC Driver for SQL Server 将支持预定义语句缓存。 在 v6.3.0 预览版之前,如果某个用户执行已预定义并存储在缓存中的查询,那么再次调用相同的查询将不会导致预定义工作。 现在,驱动程序会在缓存中查找查询并查找句柄,然后通过 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 列表,用于预定义语句的元数据缓存

新方法 说明
void setDisableStatementPooling(boolean value) 将语句池设置为 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 驱动程序提升性能和可靠性