任何查询的有效访问策略实际上都依赖于 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 ); |
该查询现在可以作为内连接查询进行有效的优化。
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |