オプティマイザ・ヒントの使用方法

TimesTen問合せオプティマイザはコストベースのオプティマイザであり、使用可能な問合せ計画を検討することにより、指定された問合せを実行する最も効率的な方法を決定します。TimesTen Scaleoutの問合せ計画は、ハッシュ分散スキームの分散スキームおよび分散キー、列および表の統計、索引の有無、データ量、一意の値の数、述語の選択性の影響を受けます。問合せ計画を手動で調べるには、ttIsql explainコマンドを実行します。『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』TimesTen問合せオプティマイザを参照してください。

オプティマイザ・ヒントを使用して、オプティマイザによって生成された実行計画に影響を与えることができます。TimesTen Scaleoutに固有のオプティマイザ・ヒントは2つあります。これらのヒントは、文レベルおよび接続レベルで有効です。文レベルでは、ヒントは、SELECT文に対してのみ有効です。

TimesTen Scaleout固有のオプティマイザ・ヒントの詳細は、『Oracle TimesTen In-Memory Database SQLリファレンス』TimesTen Scaleoutのみでサポートされているオプティマイザ・ヒントを参照してください。すべてのオプティマイザ・ヒントの詳細は、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』オプティマイザ・ヒントを使用した実行計画の変更について参照してください。

TT_GridQueryExec

TT_GridQueryExecオプティマイザ・ヒントを使用すると、問合せによって、ローカル要素から、またはすべての要素から(K-safetyが2に設定されている場合はレプリカ・セット内の要素を含む)のデータが返されるようにすることを指定できます。

このヒントを指定しない場合、問合せは1つの論理データ領域で実行されます。これはローカルでもグローバルでもありません。データの1つの完全コピーを使用して、問合せを計算します。

このヒントの有効なオプションは、LOCALおよびGLOBALです。

  • LOCAL: TimesTen Scaleoutは、ローカル要素でのみ問合せを実行します。データは、接続先の要素からローカルに取得されます。ローカル要素がデータの完全コピーを持っていない場合、TimesTen Scaleoutは結果の一部を返します。

  • GLOBAL: TimesTen Scaleoutはすべての要素からデータを取得します(結果を生成するすべてのレプリカ・セットのすべての表の行のコピーを含む)。K-safetyが2に設定されている場合、または表が複製分散スキームである場合は、重複したデータが返されます。

すべての問合せと同様に、直接接続して、SQL問合せを発行する要素は、問合せを作成してこれをグリッド内の他のすべての要素に送信します。リクエストは稼働中の要素で実行され、結果は接続している要素にローカルにレポートされます。

このヒントの構文とセマンティクスの詳細は、『Oracle TimesTen In-Memory Database SQLリファレンス』TT_GridQueryExecオプティマイザ・ヒントを参照してください。

分散スキームは、返される行数の決定ファクタです。たとえば、表7-2は、3つの分散スキームでの問合せで使用される行数を示しています。kはコピーの数を表し(例ではk=2)、eは各レプリカ・セットの1つの要素を表し(例ではe=3)、rは表内の行数を表します。

表7-2 TT_GridQueryExecオプティマイザ・ヒント

オプション 表タイプ 問合せで使用される行数

LOCAL

複製分散スキーム表

ハッシュ表で分散

参照表で分散

r

r/e 均一な分散を想定

r/e 均一な分散を想定

GLOBAL

複製分散スキーム表

ハッシュ表で分散

参照表で分散

e*k*r

k*r

k*r

次の例があります。

ノート:

読取りでは、分散ロックは取得されず、コミット済データが返されます。TT_GridQueryExec(GLOBAL)オプティマイザ・ヒントを使用する例の場合、レプリカ・セットへの書込みがレプリカへの読取り間で行われる場合、その数がすべてのレプリカで一致しない可能性があります。各レプリカにはコミット読取りの分離が許可されているため、これは予想される動作です。

ハッシュ分散スキーム表でのTT_GridQueryExecの使用

この例では、customers表でttIsql describeコマンドを使用して、表がハッシュで分散されていることを示します。この例では、customers表でSELECT COUNT (*)問合せを実行して、表の行数(1000)を返します。要素4に接続されている接続から、この例ではTT_GridQueryExec (Local)および(Global)オプティマイザ・ヒントを使用して行数を返します。返される行は、TT_GridQueryExecヒントにLocalGlobalのどちらが指定されたかに基づいて異なります。

Command> describe customers;
 
Table SAMPLEUSER.CUSTOMERS:
  Columns:
   *CUST_ID                         NUMBER (10) NOT NULL
    FIRST_NAME                      VARCHAR2 (30) INLINE NOT NULL
    LAST_NAME                       VARCHAR2 (30) INLINE NOT NULL
    ADDR1                           VARCHAR2 (64) INLINE
    ADDR2                           VARCHAR2 (64) INLINE
    ZIPCODE                         VARCHAR2 (5) INLINE
    MEMBER_SINCE                    DATE NOT NULL
  DISTRIBUTE BY HASH (CUST_ID)
 
1 table found.
(primary key columns are indicated with *)

Command> SELECT COUNT (*) FROM customers;
< 1000 >
1 row found.

SELECT elementId# FROM dual問合せを発行して、ローカル要素接続(4)を決定します。

Command> SELECT elementId# FROM dual;
< 4 >
1 row found.

この接続から、TT_GridQueryExec(LOCAL)オプティマイザ・ヒントを指定するSELECT問合せを発行します。約333行が返されると予想されます(1000/3)。

Command> SELECT /*+TT_GridQueryExec(LOCAL)*/ COUNT (*), elementId#
         FROM customers GROUP BY elementId#;
< 326, 4 >
1 row found.

ここで、TT_GridQueryExec(GLOBAL)オプティマイザ・ヒントを指定するSELECT問合せを発行します。2000行が返されると予想されます(k=2 * r=1000 = 2000)。結果を確認するには、SUM関数を使用して、6要素すべてに対して返された行の合計を計算します。

Command> SELECT /*+TT_GridQueryExec(GLOBAL)*/ COUNT (*), elementId#
         FROM customers GROUP BY elementId# 
         ORDER BY elementId#;
< 338, 1 >
< 338, 2 >
< 326, 3 >
< 326, 4 >
< 336, 5 >
< 336, 6 >
6 rows found.

Command> SELECT SUM (338+338+326+326+336+336) FROM dual;
< 2000 >
1 row found.

合計数を確認するには、TT_GridQueryExec(GLOBAL)ヒントを使用します。

Command> SELECT/*+TT_GridQueryExec(GLOBAL)*/ COUNT(*) FROM customers;
< 2000 >
1 row found.

複製分散スキーム表でのTT_GridQueryExecの使用

この例では、account_status表でttIsql describeコマンドを使用して、表が複製分散スキームであるかどうかを示します。この例では、account_status表でSELECT COUNT (*)問合せを実行して、表の行数(5)を返します。要素2に接続されている接続から、この例ではTT_GridQueryExec (Local)および(Global)オプティマイザ・ヒントを使用して行数を返します。返される行は、TT_GridQueryExecヒントにLocalGlobalのどちらが指定されたかに基づいて異なります。

Command> describe account_status; 
Table SAMPLEUSER.ACCOUNT_STATUS:
  Columns:
   *STATUS                          NUMBER (2) NOT NULL
    DESCRIPTION                     VARCHAR2 (100) INLINE NOT NULL
 DUPLICATE
 
1 table found.
(primary key columns are indicated with *)

Command> SELECT count (*) FROM account_status;                                  
< 5 >
1 row found.

Command> SELECT elementId# FROM dual;
< 2 >
1 row found.

TT_GridQueryExec(LOCAL)オプティマイザ・ヒントを指定するSELECT問合せを発行します。約5行が返されると予想されます(r = 5)。

Command> SELECT /*+TT_GridQueryExec(LOCAL)*/ COUNT (*),elementId#
         FROM account_status GROUP BY elementId#;
< 5, 2 >
1 row found.

ここで、TT_GridQueryExec(GLOBAL)オプティマイザ・ヒントを指定するSELECT問合せを発行します。30行が返されると予想されます(e=3 *k=2 * r=5= 30)。

Command> SELECT /*+TT_GridQueryExec(GLOBAL)*/ COUNT (*),elementId#
         FROM account_status GROUP BY elementId# 
         ORDER BY elementId#;
< 5, 1 >
< 5, 2 >
< 5, 3 >
< 5, 4 >
< 5, 5 >
< 5, 6 >
6 rows found.

合計数を確認するには、TT_GridQueryExec(GLOBAL)ヒントを使用します。

Command> SELECT /*+TT_GridQueryExec(GLOBAL)*/ COUNT (*) FROM account_status;
< 30 >
1 row found.

参照分散スキーム表でのTT_GridQueryExecの使用

この例では、accounts表でttIsql describeコマンドを使用して、表が参照で分散されていることを示します。この例では、accounts表でSELECT COUNT (*)問合せを実行して、表の行数(1010)を返します。要素1に接続されている接続から、この例ではTT_GridQueryExec (Local)および(Global)オプティマイザ・ヒントを使用して行数を返します。返される行は、TT_GridQueryExecヒントにLocalGlobalのどちらが指定されたかに基づいて異なります。

Command> describe accounts;
Table SAMPLEUSER.ACCOUNTS:
  Columns:
   *ACCOUNT_ID                      NUMBER (10) NOT NULL
    PHONE                           VARCHAR2 (15) INLINE NOT NULL
    ACCOUNT_TYPE                    CHAR (1) NOT NULL
    STATUS                          NUMBER (2) NOT NULL
    CURRENT_BALANCE                 NUMBER (10,2) NOT NULL
    PREV_BALANCE                    NUMBER (10,2) NOT NULL
    DATE_CREATED                    DATE NOT NULL
    CUST_ID                         NUMBER (10) NOT NULL
  DISTRIBUTE BY REFERENCE (FK_CUSTOMER)
1 table found.
(primary key columns are indicated with *)

Command> SELECT COUNT (*) FROM accounts;
< 1010 >
1 row found.

Command> SELECT elementId# FROM dual;
< 1 >
1 row found.

TT_GridQueryExec(LOCAL)オプティマイザ・ヒントを指定するSELECT問合せを発行します。約336行が返されると予想されます(1010/3)。

Command> SELECT /*+TT_GridQueryExec(LOCAL)*/ COUNT (*), elementId#
         FROM accounts GROUP BY elementId#;
< 339, 1>
1 row found.

ここで、TT_GridQueryExec(GLOBAL)オプティマイザ・ヒントを指定するSELECT問合せを発行します。2020行が返されると予想されます(k=2 * r=1010 = 2020)。結果を確認するには、SUM関数を使用して、6要素すべてに対して返された行の合計を計算します。

Command> SELECT /*+TT_GridQueryExec(GLOBAL)*/ COUNT (*), elementId#
         FROM accounts GROUP BY elementId# 
         ORDER BY elementId#;
< 339, 1 >
< 339, 2 >
< 332, 3 >
< 332, 4 >
< 339, 5 >
< 339, 6 >
6 rows found.

Command> SELECT SUM (339+339+332+332+339+339) FROM dual;
< 2020 >
1 row found.

合計数を確認するには、TT_GridQueryExec(GLOBAL)ヒントを使用します。

Command> SELECT/*+TT_GridQueryExec(GLOBAL)*/ COUNT(*) FROM accounts;
< 2020 >
1 row found.

TT_PartialResult

TT_PartialResultオプティマイザ・ヒントを使用すると、データを使用できない場合に、問合せによって結果の一部が返されるようにするか、エラーが返されるようにするかを指定できます。

レプリカ・セット内のすべての要素を使用できない場合に、問合せによって結果の一部が返されるようにするには、TT_PartialResult(1)を使用します。

レプリカ・セット内のすべての要素を使用できず、必要なデータを使用できない場合に、問合せによってエラーが返されるようにするには、TT_PartialResult(0)を使用します。各レプリカ・セットの少なくとも1つの要素が使用可能であるか、問合せに必要なデータが使用可能な場合、オプティマイザは問合せ結果を正常に返し、エラーは発生しません。

デフォルトはTT_PartialResult(0)です。

このヒントの構文とセマンティクスの詳細は、『Oracle TimesTen In-Memory Database SQLリファレンス』TT_PartialResultオプティマイザ・ヒントを参照してください。

TT_PartialResultを使用した結果の調査

この例では、elementId#replicaSetId#およびdataspaceId#疑似列を選択して、問合せに含まれるデータ行を探します。要素3および4を使用できないようにします。TT_PartialResultを0に設定すると、レプリカ・セットを使用できない場合はエラーが返されます。TT_PartialResultを1に設定すると、使用可能な要素から結果の一部が返されます。

Command> SELECT elementId#,replicasetId#,dataspaceId#, last_name,first_name 
         FROM customers WHERE last_name LIKE ('%Wh%') ORDER BY last_name;
< 6, 3, 2, Whitaker, Armand >
< 4, 2, 2, Whitaker, Ariel >
< 6, 3, 2, White, Carlene >
< 6, 3, 2, White, Marcelo >
< 4, 2, 2, White, Dona >
< 4, 2, 2, White, Ellyn >
< 4, 2, 2, White, Nora >
< 4, 2, 2, White, Phylis >
8 rows found.

Command> SELECT /*+TT_PartialResult(0)*/ elementId#,replicasetId#,dataspaceId#,
           last_name,first_name FROM customers
         WHERE last_name like ('%Wh%') ORDER BY last_name;
< 6, 3, 2, Whitaker, Armand >
< 4, 2, 2, Whitaker, Ariel >
< 6, 3, 2, White, Carlene >
< 6, 3, 2, White, Marcelo >
< 4, 2, 2, White, Dona >
< 4, 2, 2, White, Ellyn >
< 4, 2, 2, White, Nora >
< 4, 2, 2, White, Phylis >
8 rows found.

Command> SELECT /*+TT_PartialResult(1)*/ elementId#,replicasetId#,dataspaceId#,
           last_name,first_name FROM customers
         WHERE last_name LIKE ('%Wh%') ORDER BY last_name;
< 6, 3, 2, Whitaker, Armand >
< 4, 2, 2, Whitaker, Ariel >
< 6, 3, 2, White, Carlene >
< 6, 3, 2, White, Marcelo >
< 4, 2, 2, White, Dona >
< 4, 2, 2, White, Ellyn >
< 4, 2, 2, White, Nora >
< 4, 2, 2, White, Phylis >
8 rows found.

要素4は使用できません。同じ結果が予想されます。要素3は使用できます。

Command> SELECT /*+TT_PartialResult(1)*/ elementId#,replicasetId#,dataspaceId#,
           last_name,first_name FROM customers
          WHERE last_name LIKE ('%Wh%') ORDER BY last_name;
< 6, 3, 2, Whitaker, Armand >
< 3, 2, 1, Whitaker, Ariel >
< 6, 3, 2, White, Carlene >
< 6, 3, 2, White, Marcelo >
< 3, 2, 1, White, Dona >
< 3, 2, 1, White, Ellyn >
< 3, 2, 1, White, Nora >
< 3, 2, 1, White, Phylis >
8 rows found.

Command> SELECT /*+TT_PartialResult(0)*/ elementId#,replicasetId#,dataspaceId#,
           last_name,first_name FROM customers
         WHERE last_name LIKE ('%Wh%') ORDER BY last_name;
< 6, 3, 2, Whitaker, Armand >
< 3, 2, 1, Whitaker, Ariel >
< 6, 3, 2, White, Carlene >
< 6, 3, 2, White, Marcelo >
< 3, 2, 1, White, Dona >
< 3, 2, 1, White, Ellyn >
< 3, 2, 1, White, Nora >
< 3, 2, 1, White, Phylis >
8 rows found.

これで、要素3は使用できなくなります。レプリカ・セット2は使用できません。TT_PartialResultを1に設定すると、結果の一部が返されると予想されます。TT_PartialResultを0に設定すると、エラーが返されると予想されます。

Command> SELECT /*+TT_PartialResult(1)*/ elementId#,replicasetId#,dataspaceId#,
           last_name,first_name FROM customers
         WHERE last_name LIKE ('%Wh%') ORDER BY last_name;
< 6, 3, 2, Whitaker, Armand >
< 6, 3, 2, White, Carlene >
< 6, 3, 2, White, Marcelo >
3 rows found.

Command> SELECT /*+TT_PartialResult(0)*/ elementId#,replicasetId#,dataspaceId#,
           last_name,first_name FROM customers
         WHERE last_name LIKE ('%Wh%') ORDER BY last_name;
 3723: Replica set 2 down
The command failed.