Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » SQL Anywhere 服务器 - SQL 的用法 » 查询处理 » 查询优化与执行

 

语义查询转换

为了高效运行,SQL Anywhere 将查询重写为在语义上等效但在语法上不同的形式。SQL Anywhere 可执行许多不同的重写操作。

如果读取访问计划,则经常会发现其并不对应于初始语句的文字解释。例如,为使 SQL 语句更加有效,优化程序会尽可能多地尝试用连接重写子查询。

在查询重写阶段,SQL Anywhere 会执行多个转换以搜索更高效和更方便的查询表示。由于查询可能被重写为语义上等效的查询,则计划看起来可能会与初始查询的文字解释有很大不同。常见的操作包括:

  • 排除不必要的 DISTINCT 条件

  • 取消子查询嵌套

  • 将谓语推入执行了 UNION 或 GROUP 的视图和派生表中

  • 优化 OR 和 IN 列表谓语

  • 优化 LIKE 谓语

  • 将外连接转换为内连接

  • 排除外连接和内连接

  • 通过谓语推导发现可利用的条件

  • 排除不必要的大小写转换

  • 将子查询重写为 EXISTS 谓语

注意

如果游标是可更新的,则不能对主查询块执行某些查询重写优化。将游标声明为只读以利用优化。请参见选择游标类型DECLARE CURSOR 语句 [ESQL] [SP]

有关在主查询块是可更新游标时不能执行的优化的示例,请参见排除不必要的内连接和外连接

一些在查询重写阶段执行的重写优化可以在由 REWRITE 函数返回的结果中观察到。请参见REWRITE 函数 [Miscellaneous]

示例

与 SQL 语言定义不同,一些语言对 AND 和 OR 运算有严格的行为要求。一些语言可确保将首先对左侧条件求值。如果随后可以确定整个条件为真,编译器将确保不对右侧条件求值。

这样,可以将那些在其它情况下需要两个嵌套 IF 语句的条件合并成一个条件。例如,在 C 语言中,您可以按如下方式在使用指针之前测试该指针是否为 NULL。可以使用下面第二个语句中显示的语法代替第一个语句中的嵌套条件:

if ( X != NULL ) {
   if ( X->var != 0 ) {
      ... statements ...
   }
}
if ( X != NULL && X->var != 0 ) {
      ... statements ...
}

与 C 不同,SQL 没有此类有关执行顺序的规则。SQL Anywhere 会在适当的时候自由地重新排列这些条件的顺序。由于 SQL 语言规范不区分这些顺序,因此初始形式与重新排序后的形式在语义上是等效的。特别是,查询优化程序可以任意地将 WHERE、HAVING 或 ON 子句中的谓语重新排序。


排除不必要的 DISTINCT 条件
取消子查询嵌套
将谓语推入执行了 UNION 或 GROUP 的视图和派生表中
优化 OR 和 IN 列表谓语
优化 LIKE 谓语
将外部连接转换为内部连接
排除不必要的内连接和外连接
通过谓语推导发现可利用的条件
排除不必要的大小写转换
将子查询重写为 EXISTS 谓语
内置用户定义的函数
内置简单的系统过程