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 の使用法 » クエリ処理 » クエリの最適化と実行 » オプティマイザの仕組み

 

クエリでの述部の使用

「述部」は条件式であり、論理演算子 AND や OR と組み合わせて、WHERE 句、HAVING 句、または ON 句に条件のセットを構成します。SQL では、UNKNOWN と評価される述部が FALSE として解釈されます。

インデックスを使用してテーブルからローを取り出すことができる述部を、「検索引数可能 (sargable)」であるといいます。この名前は、search argument-able というフレーズからとったものです。定数、他のカラム、または式とカラムとの比較を伴う述部は、検索引数可能です。

次に示す文の述部は、検索引数可能です。SQL Anywhere はこの文を効率的に評価するため、Employees テーブルのプライマリ・インデックスを使用します。

SELECT *
FROM Employees
WHERE Employees.EmployeeID = 102;

プランでは、これは Employees<Employees> のように表示されます。

反対に、次に示す述部は、検索引数可能ではありません。EmployeeID カラムはプライマリ・インデックスでインデックスが付けられていますが、結果にはすべてのローまたは 1 つを除くすべてのローが格納されるため、このインデックスを使用しても計算速度は上がりません。

SELECT *
FROM Employees
where Employees.EmployeeID <> 102;

プランでは、これは Employees<seq> のように表示されます。

同様に、名前が k という文字で終わるすべての従業員を検索する場合、インデックスは役に立ちません。この結果を計算するには、それぞれのローを個別に調べるしかありません。

関数

通常、カラム名に対する関数を持つ述部は、検索引数可能ではありません。たとえば、次に示すクエリにはインデックスは使用されません。

SELECT * 
FROM SalesOrders
WHERE YEAR ( OrderDate ) ='2000';

クエリを書き換えて検索引数可能にすると、関数を使用しなくても済みます。たとえば、上記のクエリを次のように書き換えることができます。

SELECT * 
FROM SalesOrders
WHERE OrderDate > '1999-12-31'
AND OrderDate < '2001-01-01';

関数値を計算カラムに格納し、このカラムのインデックスを構築すると、関数を使用するクエリが検索引数可能になります。「計算カラム」は、テーブル内の他のカラムから値を取得するカラムです。たとえば、注文の日付を保持するカラム OrderDate がある場合は、OrderDate カラムから抽出した年の値を保持する計算カラム OrderYear を作成できます。

ALTER TABLE SalesOrders
ADD OrderYear INTEGER
COMPUTE ( YEAR( OrderDate ) );

次に、カラム OrderYear のインデックスを通常どおり追加できます。

CREATE INDEX IDX_year
ON SalesOrders ( OrderYear );

次の文を実行すると、データベース・サーバは、情報を保持するインデックス・カラムがあることを認識し、そのインデックスを使用してクエリに応答します。

SELECT * FROM SalesOrders
WHERE YEAR( OrderDate ) = '2000';

計算カラムのドメインは、カラムが置換されるように、COMPUTE 式のドメインと同じにします。上記の例では、YEAR( OrderDate ) が integer ではなく string を返した場合には、オプティマイザは式の計算カラムを置換しません。その結果、必要なローの取り出しにインデックス IDX_year を使用できなくなってしまいます。

計算カラムの詳細については、計算カラムの使用を参照してください。

次に示す各例では、属性 xy は、単一テーブルのそれぞれのカラムです。属性 z は、別のテーブルに格納されています。このような属性のそれぞれにインデックスが 1 つ存在することが前提です。

検索引数可能 検索引数不可能
x = 10 x <> 10
x IS NULL x IS NOT NULL
x > 25 x = 4 OR y = 5
x = z x = y
x IN (4, 5, 6) x NOT IN (4, 5, 6)
x LIKE 'pat%' x LIKE '%tern'
x = 20 - 2 x + 2 = 20

述部が検索引数可能かどうか明らかでない場合があります。この場合、述部を、検索引数可能になるように書き換えることができます。各例では、u はアルファベット順で t の後にくるという事実を利用し、述部 x LIKE 'pat%' を x >= 'pat' and x < 'pau' に書き換えることが可能です。この形式では、属性 x のインデックスを使用して、一定範囲内の値を検索できます。幸い、SQL Anywhere では、この特殊な変形を自動で行います。

テーブルでのインデックス検索に使用される検索引数可能な述部は、「マッチング」述部です。WHERE 句には、多くのマッチング述部が含まれることがあります。最も適切な述部は、ジョイン方式によって決まります。オプティマイザは、ジョイン方式の変更を検討する場合、マッチング述部の選択を再評価します。述部の推定による利用可能な条件の発見を参照してください。