连接排除重写优化会通过从查询中排除表(如果这样做足够安全)来降低查询的连接度。通常,此优化应用于定义为主键到外键连接或主键到主键连接的内连接。连接排除优化也可以应用于外连接中使用的表(虽然使这种优化有效的条件要复杂得多)。
此优化不排除可使用 UPDATE 或 DELETE WHERE CURRENT 更新的表(即使这样做是正确的)。这会对查询的性能造成负面影响。然而,如果查询为只读,则可以在 SELECT 语句中指定 FOR READ ONLY,以确保执行连接排除。注意,尽管主查询块中的表是可更新的,但在子查询或嵌套派生表中出现的表是固有不可更新的。
简而言之,该重写优化适用于以下三种主要连接:
连接属于主键到外键连接,且在查询中只引用主表中的主键列。在这种情况下,如果主键表是不可更新的,则它会被排除。
连接属于同一表的两个实例之间的主键到主键连接。在这种情况下,如果其中一个表是不可更新的,则它会被排除。
连接属于外连接,且提供空值的表表达式具有以下属性:
对于外连接的保留一侧的每一行,提供空值的表表达式最多返回一行。
在外连接以外的其余查询中,不需要任何由提供空值的表表达式所生成的表达式。
例如,在下面的查询中,连接属于主键到外键的连接,主键表、Products 表可以被排除:
SELECT s.ID, s.LineID, p.ID FROM SalesOrderItems s KEY JOIN Products p FOR READ ONLY; |
该查询将被重写为:
SELECT s.ID, s.LineID, s.ProductID FROM SalesOrderItems s WHERE s.ProductID IS NOT NULL FOR READ ONLY; |
由于 SalesOrderItems 表中具有引用 Products 表的 NULL 外键的任何行都不会出现在结果中,因此第二个查询在语义上与第一个查询等效。
在以下查询中,如果提供空值的表表达式不能为保留一侧的任何行生成多个行,且在 LEFT OUTER JOIN 上没有使用 Products 表中的任何列,则 OUTER JOIN 可以被排除。
SELECT s.ID, s.LineID FROM SalesOrderItems s LEFT OUTER JOIN Products p ON p.ID = s.ProductID WHERE s.Quantity > 5 FOR READ ONLY; |
该查询将被重写为:
SELECT s.ID, s.LineID FROM SalesOrderItems s WHERE s.Quantity > 5 FOR READ ONLY; |
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |