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

 

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

查询经常会限制视图的结果,使其只返回少数几个记录。在视图包含 GROUP BY 或 UNION 的情况下,最好让数据库服务器只计算所需行的结果。当且仅当谓语独占引用单个视图或派生表中的列时,才对其执行谓语推入。例如,不会将连接谓语推入视图中。

示例

假定您按如下方式定义了 ProductSummary 视图:

CREATE VIEW ProductSummary( ID, 
        NumberOfOrders, 
        TotalQuantity) AS
SELECT ProductID, COUNT( * ), sum( Quantity )
FROM SalesOrderItems
GROUP BY ProductID;

对于所订购的每一件产品,ProductSummary 视图都将返回包含该产品的订单数以及所有订单订购的产品总数。现在假定此视图上有以下查询:

SELECT *
FROM ProductSummary
WHERE ID = 300;

该查询将输出限制为只包括其 ID 列中的值为 300 的行。该查询以及视图定义中的查询可以合并为以下在语义上等效的 SELECT 语句:

SELECT ProductID, COUNT( * ), SUM( Quantity )
FROM SalesOrderItems
GROUP BY ProductID
HAVING ProductID = 300;

此查询不复杂的一项执行计划涉及计算每一件产品的集合,然后将结果限制为产品 ID 为 300 的一行。但是,由于 ProductID 列是分组列,可以将该列上的 HAVING 谓语推入查询的 WHERE 子句,从而生成以下语句:

SELECT ProductID, COUNT( * ), SUM( Quantity )
FROM SalesOrderItems
WHERE ProductID = 300
GROUP BY ProductID;

此 SELECT 语句会显著减少所需的计算。如果该谓语具有足够的选择性,则优化程序现在可以使用 ProductID 上的索引只检索产品 ID 为 300 的那些行,而不用按顺序扫描 SalesOrderItems 表。

相同的优化也用于包含 UNION 或 UNION ALL 的视图。