准备好的执行

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse AnalyticsAnalytics Platform System (PDW)

ODBC API 将准备好的执行定义为减少与重复执行 Transact-SQL 语句相关的分析和编译开销的方法。 该应用程序生成一个包含 SQL 语句的字符串,然后分两个阶段执行该语句。 它调用 SQLPrepare 函数 一次,以便数据库引擎分析语句并将其编译为执行计划。 然后,它为准备的执行计划的每次执行调用 SQLExecute 。 这节省了每次执行的分析和编译开销。 应用程序通常使用准备好的执行来重复执行相同的参数化 SQL 语句。

对于多数数据库中的需要执行三次或四次以上的语句,准备好的执行要比直接执行更快速。这主要是因为准备好的执行仅需编译一次语句,而直接执行的语句在每次执行时都需要编译。 准备好的执行还可以减少网络流量,因为驱动程序在每次执行语句时都可以向数据源发送执行计划标识符及参数值,而不是整个 SQL 语句。

SQL Server通过改进的算法来检测和重用 SQLExecDirect 中的执行计划,减少直接执行和准备执行之间的性能差异。 这使直接执行的语句也具备了准备好的执行的某些性能优势。 有关详细信息,请参阅 直接执行

SQL Server还为准备好的执行提供本机支持。 执行计划基于 SQLPrepare 生成,稍后在调用 SQLExecute 时执行。 由于在 SQLPrepare 上生成临时存储过程不需要SQL Server,因此 tempdb 中的系统表没有额外的开销。

出于性能原因,在调用 SQLExecute 或执行元属性操作(如 ODBC) 中的 SQLDescribeColSQLDescribeParam ) (之前,将推迟语句准备。 此选项为默认行为。 正在准备的语句如有任何错误,需等到执行该语句或执行元属性操作后才会发现。 将SQL Server Native Client ODBC 驱动程序特定的语句属性SQL_SOPT_SS_DEFER_PREPARE设置为SQL_DP_OFF可以关闭此默认行为。

在延迟准备的情况下,在调用 SQLExecute 之前调用 SQLDescribeColSQLDescribeParam 会生成到服务器的额外往返。 在 SQLDescribeCol 上,驱动程序从查询中删除 WHERE 子句,并将其发送到具有 SET FMTONLY ON 的服务器,以获取查询返回的第一个结果集中的列的说明。 在 SQLDescribeParam 上,驱动程序调用服务器以获取查询中任何参数标记所引用的表达式或列的说明。 此方法也存在一些限制,如无法解析子查询中的参数。

SQLPrepare 与 SQL Server Native Client ODBC 驱动程序过度使用会降低性能,尤其是在连接到早期版本的 SQL Server 时。 不应对执行一次的语句使用准备好的执行。 对于执行一次的语句,准备好的执行要比直接执行慢,因为它需要多进行一次从客户端到服务器的网络往返。 在早期版本的 SQL Server它还会生成临时存储过程。

预定义语句不能用于在 SQL Server 上创建临时对象。

一些早期的 ODBC 应用程序在使用 SQLBindParameter 时都使用 SQLPrepareSQLBindParameter 不需要使用 SQLPrepare,它可以与 SQLExecDirect 一起使用。 例如,将 SQLExecDirectSQLBindParameter 配合使用,从仅执行一次的存储过程检索返回代码或输出参数。 不要将 SQLPrepareSQLBindParameter 一起使用,除非多次执行同一语句。

另请参阅

(ODBC) 执行语句