X

Big Data、Data Integration、Data Lakeに関するテクノロジー、製品・サービス情報、セミナー情報などをお届けします

Big Data SQL - Parallel Queryを実行

もちろん、全てのクエリがオフロードできるわけではないし、SQLの全てのパートがCell(Storage)側で実行できるわけではありません。極めて複雑なクエリや、PL/SQLを含むものもあります。そのようなクエリの性能向上には、Oracle Databaseのパラレルクエリを使うことができます。パラレルクエリは、Big Data SQLと一緒に使うこともできるし、ユーザやアプリケーション側からは全く違いがない(意識しなくて良い)のも利点です。

今回は2つのSQLを、それぞれシリアルクエリ・パラレルクエリとして実行した場合を見ていきます。

①:ある複雑なクエリ

ここで、ある複雑なクエリを見てみましょう。そのクエリは多くのフィルタリングリソースと、データベースリソース(ソート処理など)も必要です。オフロードできない関数である、RANKを見てみましょう。

SQL> select NAME, offloadable, AGGREGATE FROM
v$sqlfn_metadata
WHERE NAME = 'RANK';

NAME    OFF AGG
------- --- ---
RANK    NO  NO
RANK    NO  YES

RANK関数を使うクエリを準備します。

SQL> SELECT /*+ NOPARALLEL */
RANK() OVER(PARTITION BY ws.ws_bill_customer_sk ORDER BY ws.ws_ship_date_sk), ws.ws_item_sk
FROM WEB_SALES ws
WHERE
ws.ws_sold_date_sk > 245
OFFSET 500000 ROWS FETCH NEXT 10 ROWS ONLY;

まずは、シリアルモードで実行し(/*+ NOPARALLEL */ ヒントで指定)、結果を見てみましょう。Oracle Enterprise ManagerのSQL Monitorを使います。



データベース側で多くのCPUイベントの発生が確認できます。

次に、同じクエリをパラレル度を変えて実行してみます。/*+ PARALLEL(4) */ ヒントでパラレル度=4を指定。

SQL> SELECT /*+ PARALLEL(4) */
RANK() OVER(PARTITION BY ws.ws_bill_customer_sk ORDER BY ws.ws_ship_date_sk), 
ws.ws_item_sk
FROM WEB_SALES ws
WHERE
ws.ws_sold_date_sk > 245
OFFSET 500000 ROWS FETCH NEXT 10 ROWS ONLY;

最初と同じクエリを実行していますが、データベース側のパラレル度が異なります。データベース側の処理が速く実行できればできるほど、より多くのIO待機(Storage Waits) を見ることになります。ストレージを待機するほど十分に速く、処理が進んでいるということです。

更に、Hadoop側で何が起きているか、Hadoop側のDisk使用率を見てみましょう。

  • グラフ左側:シリアルクエリは、低いIOワークロード
    これはDatabase側の処理の遅延に伴うもので、言い換えると、Database側は、Hadoopから届くデータを処理しきれるだけの十分なリソースを持っていないということです。
    Cellのパラレル度は、データベースのパラレル度に直接は依存しないが、副作用として変わりうる(このクエリの例のように)。
  • グラフ右側:パラレルクエリは、高いIOワークロード(Disk使用率が100%近い)
    パラレル度を上げると、データベースがより多くのCPUリソースを投入でき、結果、HadoopのI/Oパワーをほぼ使い切っています。結果、実行時間は短縮しました。

実行時間:

  • シリアル(DOP=1): 7.1分
  • パラレル(DOP=4): 3.2分

※DOP=Degree of Parallelism, パラレル度

この結果は、Big Data SQLがこのケースで有益ではないことを示すものではありません。データ型変換と列のプルーニングはStorageサイドで行われます。このSQLでよりよい性能を得るには、データベース側のパラレル化が必要でした。

②:仕事のほとんどをCell側で行うようなクエリ

それゆえに、仕事のほとんどをCell側で行うようなクエリでは、シリアルクエリとパラレルクエリの実行時間の差は小さくなります。次の例で試してみましょう。

SQL>  SELECT /*+ noparallel monitor*/ COUNT(1)
FROM WEB_SALES ws
WHERE
ws.ws_sold_date_sk = 2451507
AND ws.ws_sold_time_sk=70565
AND ws.ws_bill_customer_sk=19628510
AND ws.ws_ext_discount_amt=4433.48;

 

待機イベントのほとんど(99%)が、”cell external table smart scan” であり、Cell側に関連するものです。そして、パラレル実行の場合に何が起きているか見てみると興味深いです。


上のクエリを /*+ parallel(4) */ ヒントに変えて実行します。

待機イベントは同じく、”cell external table smart scan” です。前の例のクエリとは異なり、実行時間とCell Disk Utilizationは、シリアル実行もパラレル実行もほぼ同じです。

実行時間:

  • シリアル(DOP=1): 3.1分
  • パラレル(DOP=4): 2.9分

この理由は、すべての処理はCell側で行われ、データベース側のパラレル度は処理時間に影響しなかったからです。

 

Cell側(Hadoop側)のパラレル度

実際は、Cell側(Hadoopノード)も独自のパラレル度を持っています。ユーザがそれを制御することは出来ません。しかし実際は、それぞれのCell(Hadoopノード)が複数のブロックをパラレルに処理しています。シリアルクエリを実行した場合、Cell側の全てのパラレルスレッドと連動します。

上の図のように、それぞれのCell (Hadoopノード)は独自のパラレル度を持ちます(ここではNとする)。シリアルクエリはこれら全てのパラレルスレッドと協調して動きます。

 

パラレルクエリの例では、Query Coordinator(QC)が存在し、QCはパラレル実行プロセス(PX)を制御します。それぞれのパラレル実行プロセス(PX)は、自分に割り当てられたパートのCell(Hadoop)から届く入力データを扱うことと、その部分のパラレルスレッドと協調して動く責任があります。

 

上の図はデータベースのパラレル度がDOP=2で、そのときにそれぞれのPXがCell側のパラレルスレッドAおよびBをそれぞれ制御する様子を示します。

重要なのは、AとBの合計が、Nスレッドであることです。つまり、データベース側で異なるDOPを指定しても(例えば、/*+ noparallel */, /*+ parallel(4) */, /*+ parallel(32) */)、Cell側(Hadoop側)では、同じパラレル度になる、ということです。

本投稿はBig Data SQL Quick Start. Parallel Query - Part3.を元に投稿しています。

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.