准备好的执行

适用于:SQL Server Azure SQL 数据库 Azure SQL 托管实例 Azure Synapse Analytics Analytics 平台系统(PDW)

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

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

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

SQL Server 还为准备的执行提供本机支持。 执行计划基于 SQLPrepare 生成,并在调用 SQLExecute执行。 由于 SQL Server 不需要在 SQLPrepare生成临时存储过程,因此 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 上创建临时对象。

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

另请参阅

执行语句 (ODBC)