本文提供有关两项改进驱动程序性能的更改的信息。
预定义语句的 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_prepare 或 sp_prepexec,并实际设置预定义的语句句柄。 以后的执行调用 sp_execute。 如果该语句仅执行一次,则此行为无需在预定义语句关闭时使用 sp_unprepare。 可以通过调用 setDefaultEnablePrepareOnFirstPreparedStatementCall() 来更改此选项的默认值。 |
| void setEnablePrepareOnFirstPreparedStatementCall(布尔值) | 指定特定连接实例的行为。 如果该值为 false,则第一次执行调用 sp_executesql,并且不准备语句。 如果发生第二次执行,则它会调用 sp_prepare 或 sp_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_prepare 或 sp_prepexec,并设置一个预备语句句柄。 以后的执行调用 sp_execute。 如果语句仅执行一次,则此行为无需 sp_unprepare 关闭准备的语句。 |
| boolean getEnablePrepareOnFirstPreparedStatementCall() | 如果此配置返回 false,则预定义语句的第一次执行将调用 sp_executesql,并且不预定义语句。 如果发生第二次执行,则它会调用 sp_prepare 或 sp_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 语句参数性能提高性能和可靠性