SQL 言語で適当な構文が指定されている場合、文をネストされたクエリとして表すことができます。ただし、通常、ネストされたクエリをジョインとして書き換えると、SQL Anywhere がサブクエリの WHERE 句にある高度な選択条件をうまく利用できるようになるため、文の実行がさらに効率的になり、最適化もさらに効果的なものとなります。一般的に、サブクエリのネスト解除は、FROM 句にテーブルを多くても 1 つだけ含んだ相関サブクエリに対して常に実行されます。これらの相関サブクエリは、ANY、ALL、EXISTS の各述部で使用されます。クエリのセマンティクス上、サブクエリが返すローは多くても 1 つだけであると判断できる場合は、非相関サブクエリ、または FROM 句に複数のテーブルを含んだサブクエリはフラットにされます。
次の例に示すサブクエリでは、外部ブロック内の各ローに対して、多くても 1 つのローしか一致させられません。多くても 1 つのローしか一致させられないため、SQL Anywhere は、これを内部ジョインに変換できるものと見なします。
SELECT s.* FROM SalesOrderItems s WHERE EXISTS ( SELECT * FROM Products p WHERE s.ProductID = p.ID AND p.ID = 300 AND p.Quantity > 20); |
変換後、同じ文がジョイン構文を使用して、内部的に表現されます。
SELECT s.* FROM Products p JOIN SalesOrderItems s ON p.ID = s.ProductID WHERE p.ID = 300 AND p.Quantity > 20; |
p<Products> JNL s<FK_ProductID_ID>
同様に、次に示すクエリのサブクエリには、結合 EXISTS 述部があります。このサブクエリでは、1 つ以上のローを一致させることができます。
SELECT p.* FROM Products p WHERE EXISTS ( SELECT * FROM SalesOrderItems s WHERE s.ProductID = p.ID AND s.ID = 2001); |
SQL Anywhere は、SELECT リストに DISTINCT を使って、このクエリを内部ジョインに変換します。
SELECT DISTINCT p.* FROM Products p JOIN SalesOrderItems s ON p.ID = s.ProductID WHERE s.ID = 2001; |
Work[ DistH[ s<FK_ID_ID> JNL p<Products> ] ]
サブクエリで、外部ブロックの各ローに対して多くても 1 つのローしか一致しない場合、SQL Anywhere は、比較しているサブクエリを削除することもできます。これは次のようなクエリで行われます。
SELECT * FROM Products p WHERE p.ID = ( SELECT s.ProductID FROM SalesOrderItems s WHERE s.ID = 2001 AND s.LineID = 1 ); |
SQL Anywhere は、このクエリを次のように書き換えます。
SELECT p.* FROM Products p, SalesOrderItems s WHERE p.ID = s.ProductID AND s.ID = 2001 AND s.LineID = 1; |
s<SalesOrderItems> JNL p<Products>
サブクエリのネストを解除するリライト最適化が実行される場合、DUMMY テーブルは特殊テーブルとして扱われます。サブクエリをフラットにする処理は、それが相関サブクエリではない場合でも、常に SELECT expression FROM DUMMY
形式のサブクエリに対して実行されます。
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |