ODBC 中的动态 SQL 性能

尽管静态 SQL 在许多情况下都运行良好,但有一类应用程序的数据访问无法预先确定。 例如,假设电子表格允许用户输入查询,然后电子表格将该查询发送到 DBMS 以检索数据。 编写电子表格程序时,程序员显然无法知道该查询的内容。

动态执行

为了解决此问题,电子表格使用一种称为动态 SQL 的嵌入式 SQL 形式。 与在程序中硬编码的静态 SQL 语句不同,动态 SQL 语句可以在运行时构建,并放置在字符串主机变量中。 然后,系统会将它们发送到 DBMS 进行处理。 由于 DBMS 必须在运行时为动态 SQL 语句生成访问计划,因此动态 SQL 通常比静态 SQL 慢。 编译包含动态 SQL 语句的程序时,动态 SQL 语句不会从程序中剥离,就像静态 SQL 中一样。 相反,它们将替换为将语句传递给 DBMS 的函数调用;对同一程序中的静态 SQL 语句进行正常处理。

执行动态 SQL 语句的最简单方法是使用 EXECUTE IMMEDIATE 语句。 此语句将 SQL 语句传递给 DBMS 进行编译和执行。

EXECUTE IMMEDIATE 语句的一个缺点是,每次执行该语句时,DBMS 必须完成处理 SQL 语句的五个步骤中的每一个步骤。 如果动态执行许多语句,则此过程所涉及的开销可能十分巨大,如果这些语句类似,就是一种浪费。

预定义执行

为了解决上述情况,动态 SQL 提供了一种优化的执行形式,称为预定义执行,使用以下步骤:

  1. 程序在缓冲区中构造 SQL 语句,就像对 EXECUTE IMMEDIATE 语句所做的一样。 与主机变量不同的是,可以在语句文本的任何地方用问号 (?) 替换常量,以指示稍后将提供常量的值。 问号称为参数标记。

  2. 程序使用 PREPARE 语句将 SQL 语句传递给 DBMS,该语句请求 DBMS 分析、验证和优化语句并为其生成执行计划。 然后,程序使用 EXECUTE 语句(而不是 EXECUTE IMMEDIATE 语句)稍后执行 PREPARE 语句。 它通过名为 SQL 数据区域或 SQLDA 的特殊数据结构传递语句的参数值。

  3. 程序可以重复使用 EXECUTE 语句,每次执行动态语句时提供不同的参数值。

预定义执行仍与静态 SQL 不同。 在静态 SQL 中,在编译时执行 SQL 语句的前四个步骤。 在预定义执行中,这些步骤仍在运行时进行,但它们仅执行一次。 仅当调用 EXECUTE 时,才会执行计划。 此行为有助于消除动态 SQL 体系结构固有的某些性能缺点。

另请参阅

EXECUTE (Transact-SQL)
sp_executesql (Transact-SQL)