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 の使用法 » クエリ処理 » クエリの最適化と実行 » セマンティック・クエリ変形

 

サブクエリのネスト解除

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 形式のサブクエリに対して実行されます。