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 に関する 1 つのローだけに制限します。ただし、ProductID カラムの HAVING 述部はグループ化カラムなので、次のようにクエリの WHERE 句にプッシュできます。

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

この SELECT 文によって、必要な計算が大幅に減少します。この述部に十分な選択性があれば、オプティマイザは ProductID のインデックスを使用して製品 300 のローだけを取り出すことができます。SalesOrderItems テーブルの逐次スキャンは行いません。

これと同じ最適化は、UNION または UNION ALL を含むビューにも使用されます。