8 結合グループによる結合の最適化
結合グループは、効果的に結合できる1つ以上の列をリストするユーザー作成ディクショナリです。
この章のトピックは、次のとおりです:
8.1 インメモリー結合について
結合は、データ・ウェアハウジング・ワークロードの不可欠な一部です。結合される表がメモリーに格納されている場合、IM列ストアにより、結合のパフォーマンスが向上します。
スキャンおよび結合処理が高速化されるため、ブルーム・フィルタを使用する複雑な複数表結合および単純な結合には、IM列ストアが役立ちます。データ・ウェアハウジング環境では、最も頻繁に使用される結合には、1つのファクト表と1つ以上のディメンション表が関与しています。
次の結合は、表がIM列ストアに移入される場合に、より高速に実行されます。
-
ブルーム・フィルタを使用できる結合
-
複数の小規模なディメンション表の、1つのファクト表への結合
-
主キーと外部キーの関係がある2つの表の間の結合
8.2 結合グループについて
IM列ストアが有効になっている場合、データベースでは、結合グループを使用して、IM列ストアに移入された表の結合を最適化できます。
結合グループは、一連の表が頻繁に結合される列のセットです。列セットには、1つ以上の列が含まれ、最大255の列が含まれます。表セットには、1つ以上の内部表が含まれます。外部表はサポートされていません。
結合グループ内の列は、同じ表内または異なる表内にある可能性があります。たとえば、sales
とtimes
がtime_id
列で頻繁に結合される場合は、(times(time_id), sales(time_id))
の結合グループを作成できます。employees
表がemployee_id
列でそれ自体に結合されることが多い場合、結合グループは(employees(employee_id))
である可能性があります。
ノート:
同じ列が複数の結合グループのメンバーになることはできません。
結合グループを作成すると、データベースにより、その結合グループで参照されている表の現在のインメモリー・コンテンツが無効になります。後続の再移入により、データベースで、共通ディクショナリによる表のIMCUの再エンコードが引き起こされます。このため、最初に結合グループを作成し、その後、表に移入することをお薦めします。
CREATE INMEMORY JOIN GROUP
文を使用して結合グループを作成します。結合グループに列を追加するか、結合グループから列を削除するには、ALTER INMEMORY JOIN GROUP
文を使用します。DROP INMEMORY JOIN GROUP
文を使用して結合グループを削除します。
ノート:
Oracle Active Data Guardでは、スタンバイ・データベースで結合グループ定義が無視されます。スタンバイ・データベースでは、共通ディクショナリは使用されず、結合グループが存在しないかのように問合せが実行されます。
例8-1 結合グループの作成
この例では、hr.employees
表内およびhr.departments
表内のdepartment_id
を含む、deptid_jg
という名前の結合グループを作成します。
CREATE INMEMORY JOIN GROUP deptid_jg (hr.employees(department_id),hr.departments(department_id));
8.3 結合グループの目的
特定の問合せでは、結合グループにより、列値の解凍およびハッシュについてパフォーマンスのオーバーヘッドがなくなります。
結合グループを使用しないときは、オプティマイザでハッシュ結合を使用するがブルーム・フィルタを使用できないか、ブルーム・フィルタで行が効率的にフィルタされない場合に、データベースで、IMCUを解凍し、コストのかかるハッシュ結合を使用する必要があります。問題を示すため、スター・スキーマにsales
ファクト表およびvehicles
ディメンション表があると仮定します。次の問合せでは、これらの表が結合されますが、出力はフィルタされません。これは、データベースでブルーム・フィルタを使用できないことを意味します。
SELECT v.year, v.name, s.sales_price
FROM vehicles v, sales s
WHERE v.name = s.name;
次の図に、データベースによる2つのデータ・セットの結合方法を示します。
データベースは、次のようにハッシュ結合を実行します。
-
vehicles
表をスキャンし、述語を満たす行(このケースでは、フィルタが存在しないため、すべての行が述語を満たします)を解凍し、行をハッシュ結合に送信します。 -
解凍した行に基づいてPGAでハッシュ表を作成します
-
sales
表をスキャンし、フィルタを適用します(この場合、問合せはフィルタを指定しません) -
IMCUから一致する行を処理して、その行を結合に送信します
調査側(この例では、
sales
表)の行セットがハッシュ結合で利用できる場合は、表スキャンによって送信される行セットは圧縮された形式になります。構築側から一致する行を検索するためにローカル・ディクショナリまたは結合グループが利用されるかどうかに応じて、ハッシュ結合で行が解凍されるか、未圧縮のままにされます。 -
結合列(この場合、乗物名)を使用してハッシュ表を調べます
結合グループがv.name
列およびs.name
列に存在する場合、データベースは前述のステップをより効率的に実行します(解凍とフィルタリングのオーバーヘッドがなくなります)。結合グループの利点は次のとおりです。
-
データベースは、圧縮されたデータに対して機能します。
-
データベースは、調査行とハッシュされた行の結合キーの比較が必要になる結合キーのハッシングとハッシュ表の調査を回避します。
結合グループが存在する場合、データベースは結合列値ごとのコードを共通ディクショナリに格納します。データベースは、ディクショナリのコードを使用して結合グループの配列を作成します。すべての配列要素は、ハッシュ領域(通常は、PGAメモリー)に格納されている構築側の行をポイントしています。調査時に、各調査行は結合キーに関連付けられたコードを保持しています。データベースは、このコードを使用して配列を検索し、配列要素にポインタが存在しているかどうかを調べます。ポインタが存在する場合は一致があり、それ以外の場合は一致がありません。
-
ディクショナリ・コードは稠密および固定長であるため、領域が効率的に使用されます。
-
結合グループによる問合せの最適化は、ブルーム・フィルタを使用できないときに可能な場合があります。
8.4 結合グループの仕組み
結合グループでは、データベースによって、同じ共通ディクショナリを使用して結合グループ内のすべての列が圧縮されます。
8.4.1 結合グループでどのように共通ディクショナリが使用されるか
共通ディクショナリは、表レベルの、インスタンス固有の一連のディクショナリ・コードです。
データベースでは、基になる列で結合グループが定義されている場合に、IM列ストア内に共通ディクショナリが自動的に作成されます。共通ディクショナリにより、複数の結合列で同じディクショナリ・コードを共有できるようになります。
共通ディクショナリには、次のような利点があります。
-
共通ディクショナリからのコードでローカル・ディクショナリ内の値をエンコードします。それにより、圧縮が提供され、IMCUのキャッシュ効率が向上します
-
結合でディクショナリ・コードを使用して、ハッシュ結合中に使用されるデータ構造を構成および調査できます
-
オプティマイザにより、カーディナリティ、列値の分布などの統計を取得できます
次の図は、sales.name
列とvehicles.name
列で作成された結合グループに対応する、共通ディクショナリを示しています。
データベースで共通ディクショナリが使用される場合、各CUのローカル・ディクショナリには、元の値(AUDI
、BMW
、CADILLAC
、FORD
など)は格納されません。かわりに、ローカル・ディクショナリには、共通ディクショナリに格納されている値への参照が格納されます。たとえば、ローカル・ディクショナリではAudi
に値101
、BMW
には220
を格納できます。共通ディクショナリでは、Audi
に0
、BMW
に1
を格納できます。ローカル・ディクショナリの101
(AUDI)は、共通ディクショナリの0
(AUDI)へのポインタです。
8.4.2 結合グループでどのようにスキャンが最適化されるか
主要な最適化は、列値ではなく共通ディクショナリ・コードでの結合であり、それによって、結合にハッシュ表を使用しないようにします。
結合グループを使用してvehicles
とsales
をname
列で結合する、次のような問合せについて考察します。
SELECT v.year, v.name, s.sales_price
FROM vehicles v, sales s
WHERE v.name = s.name
AND v.name IN ('Audi', 'BMW', 'Porsche', 'VW');
次の図では、結合グループで作成された共通ディクショナリがどのように結合に役立つかを示します。
前述の図に示されているように、データベースは次のように圧縮されたデータのハッシュ結合を実行します。
-
vehicles
表をスキャンし、0
(Audi)、1
(BMW)、2
(Cadillac)などのディクショナリ・コード(元の列値ではない)をハッシュ結合に送信します。 -
PGA内で非重複共通ディクショナリ・コードの配列を構築します。
-
sales
表をスキャンし、フィルタを適用します(このケースでは、ドイツ車のみのフィルタとなります) -
一致する行を、圧縮された形式で結合に送信します。
-
ハッシュ表のプロービングではなく、配列内の対応する値を探します。それにより、結合キー列上のハッシュ関数を計算する必要がなくなります。
この例では、vehicles
表には7行のみがあります。vehicles.name
列には、次のような値があります。
Audi
BMW
Cadillac
Ford
Porsche
Tesla
VW
共通ディクショナリにより、ディクショナリ・コードが各非重複値に割り当てられます。概念的には、共通ディクショナリは、次のようになります。
Audi 0
BMW 1
Cadillac 2
Ford 3
Porsche 4
Tesla 5
VW 6
データベースで、vehicles.name
がスキャンされます。最初のIMCU内の最初のディクショナリ・コードから始まり、最後のIMCU内の最後のコードで終わります。フィルタ(ドイツ車のみ)に適合するすべての行については1
、フィルタに適合しないすべての行については0
が格納されます。概念上、配列は次のようになります。
array[0]: 1
array[1]: 1
array[2]: 0
array[3]: 0
array[4]: 1
array[5]: 0
array[6]: 1
データベースでは、次に、sales
ファクト表がスキャンされます。この例を単純化するために、sales
表には6行のみがあると仮定します。データベースでは、次のように行がスキャンされます(値ごとの共通ディクショナリ・コードを括弧で囲んで示します)。
Cadillac (2)
Cadillac (2)
BMW (1)
Ford (3)
Audi (0)
Tesla (5)
データベースでは、次に、vehicles.name
配列内を進み、一致を探します。行が一致すると、データベースにより、一致する行がその関連する共通ディクショナリ・コードとともに送信され、対応する列値がvehicles.name
およびsales.name
IMCUから取得されます。
2 -> array[2] is 0, so no join
2 -> array[2] is 0, so no join
1 -> array[1] is 1, so join
3 -> array[3] is 0, so no join
0 -> array[0] is 1, so join
5 -> array[5] is 0, so no join
8.5 ハッシュ結合で共通ディクショナリ・エンコーディングが使用される場合
通常、結合グループ内の列を結合することでパフォーマンスが向上します。
結合グループの作成時に、次の処理がデータベースによって実行されます。
-
結合キー列に対応するディクショナリ値のハッシュがキャッシュされます
-
結合キー列に対応する
NUMBER
データのバイナリ表現がキャッシュされます -
同じ共通ディクショナリで列がエンコードされます
結合グループ内の列の結合では、最初の2つの最適化が常に使用されるためパフォーマンスが向上します。たとえば、オプティマイザがハッシュ結合を選択すると、問合せはブルーム・フィルタの調査にハッシュ値を使用するようになります。問合せでIM集計結合が使用される場合、問合せはキー・ベクターへの索引付けにキャッシュされた2進数を使用します。
ハッシュ結合には、ディクショナリ・エンコーディングが使用されることも使用されないこともあります。ハッシュ結合の少なくとも1つの列にディクショナリ・エンコーディングが存在する場合、問合せでは次の方法でエンコーディングを活用できます。
-
結合グループ対応のハッシュ結合
実行時に、ハッシュ結合の両方の列が共通ディクショナリ・エンコーディング・データを保持します。実行計画は、ハッシュ結合の両側が関与する分散のないパラレル・ハッシュ結合計画か、シリアル・ハッシュ結合計画のどちらかを必ず示します。
-
エンコーディング対応のハッシュ結合
実行時に、ハッシュ結合内の1つのファクト表列がディクショナリ・エンコーディング・データを保持します。実行計画は、ハッシュ結合の右側からの分散のないパラレル・ハッシュ結合か、シリアル・ハッシュ結合計画のどちらかを必ず示します。共通ディクショナリの圧縮率が良好な場合や、パラレル・ハッシュ結合計画では結合グループ対応のハッシュ結合を活用できない場合(並列ブロードキャストなしの計画など)、問合せでは共通ディクショナリにエンコーディング対応ハッシュ結合を使用することもできます。
SQL監視レポートでは、ディクショナリの使用がColumnar Encodings Observed
フィールドとColumnar Encodings Leveraged
フィールドで示されます。この統計は累積されます。パラレル・ハッシュ結合の場合、このフィールドには、行ソースの実行に関連するすべてのスレーブ・プロセスから収集した統計が集約されます。IMCU内のローカル・ディクショナリの観点では、この統計には、右側の子行ソースで観測されたエンコーディングIDの数と、結合で利用されたエンコーディングの数が示されます。単一プロセスのハッシュ結合が共通ディクショナリを利用する場合、Columnar Encodings Leveraged
には、結合で利用されたエンコーディングの数が示されます。
次の表に、Columnar Encodings Observed
とColumnar Encodings Leveraged
に示される可能性のある値と、その組合せが意味する内容を示します。
表8-1 SQL監視レポートでの結合グループの使用
観測された列形式エンコーディング | 利用された列形式エンコーディング | エンコーディング対応ハッシュ結合の使用 | 結合グループ対応ハッシュ結合の使用 |
---|---|---|---|
存在しない |
存在しない |
なし |
なし |
正の値 |
存在しない |
なし |
なし |
正の値 |
正の値 |
あり |
なし |
存在しない |
正の値 |
なし |
はい |
たとえば、Columnar Encodings Leveraged
フィールドに4
が示されていているときに(並列度が4であると仮定)、Columnar Encodings Observed
フィールドが存在していない場合、問合せはハッシュ結合に結合グループを利用したことを意味します。Columnar Encodings Observed
フィールドが4
のときに、Columnar Encodings Leveraged
フィールドが存在しない場合、ディクショナリ・エンコーディングが存在していても、問合せでは使用されなかったことを意味します。
様々な要因によって、問合せでエンコーディング対応ハッシュ結合が使用されなくなることがあります。こうした要因には次のものがあります。
-
共通ディクショナリの圧縮率が最適でない。
-
共通ディクショナリなしで表スキャンから渡された行セットが多すぎることが問合せで観測された。
-
構築側の行の長さが長すぎる。
-
構築側の行がPGAメモリーに収まりきらない。
-
構築側に重複した結合キーがある。
関連項目:
8.6 結合グループの作成
CREATE INMEMORY JOIN GROUP
文を使用して結合グループを定義します。
結合グループの候補は、結合述語で頻繁にペアにされる列です。代表的な例に、ファクト表とディメンション表を結合する列、または表をそれ自体に結合する列などがあります。
CREATE INMEMORY JOIN GROUP
文は、結合グループをただちに定義します。これは、そのメタデータがデータ・ディクショナリに表示されることを意味します。データベースでは、共通ディクショナリはすぐには構成されません。正確に述べると、データベースでは、次回、結合グループ内で参照されている表が、IM列ストアに移入されるか再移入されるときに共通ディクショナリが構築されます。
ガイドライン
結合グループを作成、変更または削除すると、通常は、その結合グループ内で参照されている、基にあるすべての表が無効になります。そのため、表を最初に移入する前に結合グループを作成することをお薦めします。
結合グループを作成するには:
-
SQL*PlusまたはSQL Developerで、必要な権限を持つユーザーとしてデータベースにログインします。
-
次の形式の文を使用して、結合グループを作成します。
CREATE INMEMORY JOIN GROUP join_group_name ( table1(col1), table2(col2) );
たとえば、次の文は、
sales_products_jg
という結合グループを作成します。CREATE INMEMORY JOIN GROUP sales_products_jg (sales(prod_id), products(prod_id));
-
オプションで、データ・ディクショナリを問い合せて、結合グループの定義を表示します(出力例も示します)。
COL JOINGROUP_NAME FORMAT a18 COL TABLE_NAME FORMAT a8 COL COLUMN_NAME FORMAT a7 SELECT JOINGROUP_NAME, TABLE_NAME, COLUMN_NAME, GD_ADDRESS FROM DBA_JOINGROUPS; JOINGROUP_NAME TABLE_NA COLUMN_ GD_ADDRESS ------------------ -------- ------- ---------------- SALES_PRODUCTS_JG SALES PROD_ID 00000000A142AE50 SALES_PRODUCTS_JG PRODUCTS PROD_ID 00000000A142AE50
-
結合グループ内で参照されている表を移入します。または、現在移入されている場合は、それらを再移入します。
例8-2 結合グループの使用による問合せの最適化
この例では、データベースにSYSTEM
としてログインしてから、まだIM列ストアに移入されていないsales
およびproducts
のprod_id
列で結合グループを作成します。
CREATE INMEMORY JOIN GROUP
sh.sales_products_jg (sh.sales(prod_id), sh.products(prod_id));
IM列ストアへの移入のためにsh.sales
表およびsh.products
表を有効にします。
ALTER TABLE sh.sales INMEMORY;
ALTER TABLE sh.products INMEMORY;
次の問合せでは、それらの表がまだIM列ストアに移入されていないことが示されます(出力例が含まれています)。
COL OWNER FORMAT a3
COL NAME FORMAT a10
COL STATUS FORMAT a20
SELECT OWNER, SEGMENT_NAME NAME,
POPULATE_STATUS STATUS
FROM V$IM_SEGMENTS;
no rows selected
両方の表を問い合せて、それらをIM列ストアに移入します。
SELECT /*+ FULL(s) NO_PARALLEL(s) */ COUNT(*) FROM sh.sales s;
SELECT /*+ FULL(p) NO_PARALLEL(p) */ COUNT(*) FROM sh.products p;
次の問合せでは、それらの表が現在はIM列ストアに移入されていることが示されます(出力例が含まれています)。
COL OWNER FORMAT a3
COL NAME FORMAT a10
COL PARTITION FORMAT a13
COL STATUS FORMAT a20
SELECT OWNER, SEGMENT_NAME NAME, PARTITION_NAME PARTITION,
POPULATE_STATUS STATUS, BYTES_NOT_POPULATED
FROM V$IM_SEGMENTS;
OWN NAME PARTITION STATUS BYTES_NOT_POPULATED
--- ---------- ------------- -------------------- -------------------
SH SALES SALES_Q3_1998 COMPLETED 0
SH SALES SALES_Q4_2001 COMPLETED 0
SH SALES SALES_Q4_1999 COMPLETED 0
SH PRODUCTS COMPLETED 0
SH SALES SALES_Q1_2001 COMPLETED 0
SH SALES SALES_Q1_1999 COMPLETED 0
SH SALES SALES_Q2_2000 COMPLETED 0
SH SALES SALES_Q2_1998 COMPLETED 0
SH SALES SALES_Q3_2001 COMPLETED 0
SH SALES SALES_Q3_1999 COMPLETED 0
SH SALES SALES_Q4_2000 COMPLETED 0
SH SALES SALES_Q4_1998 COMPLETED 0
SH SALES SALES_Q1_2000 COMPLETED 0
SH SALES SALES_Q1_1998 COMPLETED 0
SH SALES SALES_Q2_2001 COMPLETED 0
SH SALES SALES_Q2_1999 COMPLETED 0
SH SALES SALES_Q3_2000 COMPLETED 0
DBA_JOINGROUPS
を問い合せ、結合グループに関する情報を取得します(出力例が含まれています)。
COL JOINGROUP_NAME FORMAT a18
COL TABLE_NAME FORMAT a8
COL COLUMN_NAME FORMAT a7
SELECT JOINGROUP_NAME, TABLE_NAME, COLUMN_NAME, GD_ADDRESS
FROM DBA_JOINGROUPS;
JOINGROUP_NAME TABLE_NA COLUMN_ GD_ADDRESS
------------------ -------- ------- ----------------
SALES_PRODUCTS_JG SALES PROD_ID 00000000A142AE50
SALES_PRODUCTS_JG PRODUCTS PROD_ID 00000000A142AE50
上の出力では、結合グループsales_products_jg
が同じ共通ディクショナリ・アドレスで結合されていることが示されています。
関連項目:
-
CREATE INMEMORY JOIN GROUP
文について学習するには、『Oracle Database SQL言語リファレンス』を参照してください -
DBA_JOINGROUPS
ビューについて学習するには、『Oracle Databaseリファレンス』を参照
8.7 結合グループの使用の監視
問合せで結合グループが使用されているかどうかを判断するには、グラフィカルなSQL監視レポート(推奨)を使用することも、DBMS_SQLTUNE.REPORT_SQL_MONITOR_XML
ファンクションを使用するSQL問合せを使用することもできます。
「ハッシュ結合で共通ディクショナリ・エンコーディングが使用される場合」では、SQL監視の出力を解釈する方法について説明しています。
前提条件
結合グループを監視するには、次の前提条件を満たしている必要があります。
-
結合グループが存在する必要があります。
-
結合グループによって参照される列が、結合グループの作成後に移入されている必要があります。
-
結合グループを使用可能な結合問合せを実行する必要があります。
結合グループの使用を監視するには:
-
必要な権限があるユーザーとしてデータベースにログインします。
-
次のようにして、SQL IDを格納するSQL*Plus変数を作成します。
VAR b_sqlid VARCHAR2(13)
-
結合グループ内の列で結合する問合せを実行します。
-
次のどちらかの方法を使用します。
-
グラフィカルなSQL監視レポート
SQL監視レポートはEnterprise Managerで使用できます。SQL*Plusでは、次のように
DBMS_SQL_MONITOR.REPORT_SQL_MONITOR
を使用すると、SQL監視レポートを生成できます。SET TRIMSPOOL ON SET TRIM ON SET PAGES 0 SET LINESIZE 1000 SET LONG 1000000 SET LONGCHUNKSIZE 1000000 SPOOL /tmp/long_sql.htm SELECT DBMS_SQL_MONITOR.REPORT_SQL_MONITOR( sql_id => :b_sqlid, report_level => 'ALL', TYPE => 'active') FROM DUAL; SPOOL OFF
ブラウザでレポートにアクセスし、ハッシュ結合の双眼鏡アイコンをクリックして、結合グループの統計を表示します。
-
コマンドラインでの問合せ
問合せで、
DBMS_SQLTUNE.REPORT_SQL_MONITOR_XML
ファンクションを使用します。次に例を示します。SELECT encoding_hj.rowsource_id row_source_id, CASE WHEN encoding_hj.encodings_observed IS NULL AND encoding_hj.encodings_leveraged IS NOT NULL THEN 'join group was leveraged on ' || encoding_hj.encodings_leveraged || ' processes' ELSE 'join group was NOT leveraged' END columnar_encoding_usage_info FROM (SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR_XML(session_id=>-1,sql_id=>:b_sqlid). EXTRACT(q'#//operation[@name='HASH JOIN' and @parent_id]#') xmldata FROM DUAL) hj_operation_data, XMLTABLE('/operation' PASSING hj_operation_data.xmldata COLUMNS "ROWSOURCE_ID" NUMBER PATH '@id', "ENCODINGS_LEVERAGED" NUMBER PATH 'rwsstats/stat[@id="9"]', "ENCODINGS_OBSERVED" NUMBER PATH 'rwsstats/stat[@id="10"]') encoding_hj;
-
8.7.1 SQL監視レポートを使用した結合グループの監視: 例
グラフィカルなSQL監視レポートを使用して、問合せで結合グループが利用されたかどうかを判断できるようにします。
この例では、sh.products
表およびsh.sales
表のprod_id
列で結合グループを作成してから、これらの表をこの列で結合します。sh
アカウントに管理権限を付与します。
例8-3 SQL監視レポートを使用した結合グループの監視
-
SQL*Plusで、ユーザー
sh
としてデータベースにログインします。 -
SQL IDを格納するためのSQL*Plus変数を次のように作成します。
VAR b_sqlid VARCHAR2(13)
-
次のように
INMEMORY
属性をsh.products
表およびsh.sales
表に適用します。ALTER TABLE sales NO INMEMORY; ALTER TABLE products NO INMEMORY; ALTER TABLE sales INMEMORY MEMCOMPRESS FOR QUERY; ALTER TABLE products INMEMORY MEMCOMPRESS FOR QUERY;
-
prod_id
で結合グループを作成します。CREATE INMEMORY JOIN GROUP jgrp_products_sales (products(prod_id), sales(prod_id));
-
それらの表をスキャンしてIM列ストアに移入します。
SELECT /*+ FULL(s) */ COUNT(*) FROM sales s; SELECT /*+ FULL(p) */ COUNT(*) FROM products p;
-
prod_id
列で結合する問合せを実行してから、商品売上を集計します。SELECT /*+ USE_HASH(sales) LEADING(products sales) MONITOR */ products.prod_id, products.prod_category_id, SUM(sales.amount_sold) FROM products, sales WHERE products.prod_id = sales.prod_id GROUP BY products.prod_category_id, products.prod_id;
-
DBMS_SQLTUNE.REPORT_SQL_MONITOR
を使用して、HTMLベースのSQL監視レポートを生成します。たとえば、次に示す内容のSQLスクリプトを作成して、SQL*Plusで実行します。
SET TRIMSPOOL ON SET TRIM ON SET PAGES 0 SET LINESIZE 1000 SET LONG 1000000 SET LONGCHUNKSIZE 1000000 SPOOL /tmp/jg_report.htm SELECT DBMS_SQL_MONITOR.REPORT_SQL_MONITOR( sql_id => :b_sqlid, report_level => 'ALL', TYPE => 'active') FROM DUAL; SPOOL OFF
-
ブラウザで、HTMLレポートを開きます。
次のレポート例は、結合の実行計画を示しています。ハッシュ結合の双眼鏡アイコンで、追加の統計が示されるウィンドウを開きます。
-
双眼鏡アイコンをクリックして、結合グループの統計を表示するウィンドウを開きます。
次に、統計が表示されたウィンドウの例を示します。
Columnar Encodings Leveraged
が正の値であり、Columnar Encodings Observed
が存在していないことから、結合グループが利用されたことがわかります。 -
必要に応じて、この例の後でクリーン・アップを実行します。
DROP INMEMORY JOIN GROUP jgrp_products_sales; ALTER TABLE sales NO INMEMORY; ALTER TABLE products NO INMEMORY;
関連項目:
-
DBMS_SQLTUNE.REPORT_SQL_MONITOR_XML
関数について学習するには、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照 -
V$SESSION
ビューについて学習するには、『Oracle Databaseリファレンス』を参照
8.7.2 コマンドラインからの結合グループの監視: 例
コマンドライン・ツールを使用して、問合せで結合グループが利用されたかどうかを判断できるようにします。
この例では、sh.products
表およびsh.sales
表のprod_id
列で結合グループを作成してから、これらの表をこの列で結合します。sh
アカウントに管理権限を付与します。
例8-4 コマンドラインからの結合グループの監視
-
sh
としてデータベースにログインします。 -
SQL IDを格納するためのSQL*Plus変数を次のように作成します。
VAR b_sqlid VARCHAR2(13)
-
次のように
INMEMORY
属性をsh.products
表およびsh.sales
表に適用します。ALTER TABLE sales NO INMEMORY; ALTER TABLE products NO INMEMORY; ALTER TABLE sales INMEMORY MEMCOMPRESS FOR QUERY; ALTER TABLE products INMEMORY MEMCOMPRESS FOR QUERY;
-
prod_id
で結合グループを作成します。CREATE INMEMORY JOIN GROUP jgrp_products_sales (products(prod_id), sales(prod_id));
-
それらの表をスキャンしてIM列ストアに移入します。
SELECT /*+ FULL(s) */ COUNT(*) FROM sales s; SELECT /*+ FULL(p) */ COUNT(*) FROM products p;
-
prod_id
列で結合する問合せを実行してから、商品売上を集計します。SELECT /*+ USE_HASH(sales) LEADING(products sales) MONITOR */ products.prod_id, products.prod_category_id, SUM(sales.amount_sold) FROM products, sales WHERE products.prod_id = sales.prod_id GROUP BY products.prod_category_id, products.prod_id;
-
前述の集計問合せのSQL IDを取得します。
BEGIN SELECT PREV_SQL_ID INTO :b_sqlid FROM V$SESSION WHERE SID=USERENV('SID'); END;
-
DBMS_SQLTUNE.REPORT_SQL_MONITOR_XML
を使用して、データベースで結合グループが使用されたかどうかを判断します。たとえば、次の問合せを実行します。
COL row_source_id FORMAT 999 COL columnar_encoding_usage_info FORMAT A40 SELECT encoding_hj.rowsource_id row_source_id, CASE WHEN encoding_hj.encodings_observed IS NULL AND encoding_hj.encodings_leveraged IS NOT NULL THEN 'join group was leveraged on ' || encoding_hj.encodings_leveraged || ' processes' ELSE 'join group was NOT leveraged' END columnar_encoding_usage_info FROM (SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR_XML(session_id=>-1,sql_id=>:b_sqlid). EXTRACT(q'#//operation[@name='HASH JOIN' and @parent_id]#') xmldata FROM DUAL ) hj_operation_data, XMLTABLE('/operation' PASSING hj_operation_data.xmldata COLUMNS "ROWSOURCE_ID" NUMBER PATH '@id', "ENCODINGS_LEVERAGED" NUMBER PATH 'rwsstats/stat[@id="9"]', "ENCODINGS_OBSERVED" NUMBER PATH 'rwsstats/stat[@id="10"]' ) encoding_hj;
次の出力例は、問合せで結合グループが利用されたことを示しています。
ROW_SOURCE_ID COLUMNAR_ENCODING_USAGE_INFO ------------- ---------------------------------------- 2 join group was leveraged on 1 processes
-
必要に応じて、例の後にクリーン・アップを実行します。
DROP INMEMORY JOIN GROUP jgrp_products_sales; ALTER TABLE sales NO INMEMORY; ALTER TABLE products NO INMEMORY;
関連項目:
-
DBMS_SQLTUNE.REPORT_SQL_MONITOR_XML
関数について学習するには、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照 -
V$SESSION
ビューについて学習するには、『Oracle Databaseリファレンス』を参照