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 的用法 » 查询处理 » 查询优化与执行 » 语义查询转换

 

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

任何查询的有效访问策略实际上都依赖于 WHERE、ON 和 HAVING 子句中是否存在可优化搜索条件。只有通过将 sargable 条件作为匹配谓语利用,才有可能进行索引检索。此外,只有当存在等值连接条件时,才能使用散列、合并和块嵌套循环连接。由于上述原因,SQL Anywhere 会对初始查询文本中的搜索条件进行详细的分析,以发现可供优化程序利用的简化或隐含条件。

作为一个预处理步骤,视图扩展和合并一旦发生,就会对初始语句中的谓语进行一些简化。例如:

  • 如果 X 可为空,X = X 会被重写为 X IS NOT NULL;否则将排除该谓语。

  • ISNULL(X,X) 被重写为 X

  • 如果 X 为数字列,X+0 会被重写为 X

  • 将排除 AND 1=1

  • 将排除 OR 1=0

  • 由单个元素组成的 IN 列表谓语会被转换为简单的相等条件。

在这一预处理步骤之后,SQL Anywhere 会尝试将初始搜索条件规范化为连接性规范形式 (CNF)。若要使表达式成为 CNF 的形式,该表达式中的每一项都必须用 AND 连起来。每一项都由单个原子条件或一组用 OR 连起来的条件组成。

如果将任意条件转换为 CNF,所生成的表达式可能具有相似的复杂性,但会包含大得多的条件集。SQL Anywhere 将发现这种情况,并避免单纯地将条件转换为 CNF。相反,SQL Anywhere 会分析初始表达式以查找初始搜索条件所隐含的可利用谓语,并且用 AND 将这些推导出的条件与查询连起来。如果完全的规范化需要复制占用大量资源的谓语(例如限定子查询谓语),则还将避免完全的规范化。但是,只要可行,该算法就会将 IN 列表谓语合并起来。

将搜索条件完全规范化或找到可利用的条件后,优化程序会执行传递性分析,以发现传递等同条件(主要是传递连接条件和包含常量的条件)。这样,在基于开销的优化阶段中执行连接枚举时,优化程序将具有更大的自由度,因为这些传递条件允许附加的替代连接顺序。

示例

假定初始查询如下:

SELECT e.Surname, s.ID, s.OrderDate
FROM SalesOrders s, Employees e
WHERE 
  ( e.EmployeeID = s.SalesRepresentative AND
    ( s.SalesRepresentative = 142 OR 
      s.SalesRepresentative = 1596 )
  ) OR (
     e.EmployeeID = s.SalesRepresentative AND 
     s.CustomerID = 667 );

该查询不包含连接性等值连接条件;如果不进行详细的谓语分析,优化程序将无法发现有效的访问计划。幸运的是,SQL Anywhere 能够将整个表达式转换为 CNF,从而生成等效的查询:

SELECT e.Surname, s.ID, s.OrderDate
FROM SalesOrders s, Employees e
WHERE 
   e.EmployeeID = s.SalesRepresentative AND
   ( s.SalesRepresentative = 142 OR 
     s.SalesRepresentative = 1596 OR 
     s.CustomerID = 667 );

该查询现在可以作为内连接查询进行有效的优化。