サマリー書き換えによる最適化

ここでは、Denodo クエリオプティマイザーでサマリービューを使用してクエリを書き換える方法およびいくつかのベストプラクティスについて説明します。

まず、サマリー書き換えとその仕組みについて理解するために、いくつかの例を取り上げます。これらの例を説明するために、TPC-DS ベンチマークのエンティティを使用します。このベンチマークは、小売製品サプライヤーの意思決定支援機能をモデル化します。使用するエンティティとして、売上情報を収めた store_sales、日付ディメンションを表す date_dim、store などがあります。

わかりやすくするために、以下のように店舗 ID と日付 ID で集計した総売上を収めたサマリーを作成したとします。

SELECT ss_sold_date_sk as sold_date_id, ss_store_sk as store_id, sum(ss_net_paid_inc_tax) AS total_sales, count(*) AS count_sales
FROM store_sales
GROUP by ss_sold_date_sk, ss_store_sk

この場合、クエリオプティマイザーでは、この部分的な情報を使用してさまざまなクエリを高速化することを判断できます。以下に 2 つの例を示します。

2019 年の総売上

SELECT sum(store_sales.ss_net_paid_inc_tax) AS total_sales, count(*) AS count_sales
FROM store_sales INNER JOIN date_dim ON store_sales.ss_sold_date_sk = date_dim.d_date_sk
WHERE date_dim.d_year = 2019
../../../../../_images/summary_rewrite_trace_example1.png

このクエリの場合、クエリオプティマイザーでは、サマリーにキャッシュされている日付別および店舗別の総売上にフィルターを適用するだけで、2019 年の最終的な集計結果が得られます。

店舗部門別の総売上

SELECT s_division_name,  sum(store_sales.ss_net_paid_inc_tax) AS total_sales, count(*) AS count_sales
FROM store_sales INNER JOIN date_dim ON store_sales.ss_sold_date_sk = date_dim.d_date_sk
JOIN store ON(store.s_store_sk = store_sales.ss_store_sk)
GROUP BY s_division_name
../../../../../_images/summary_rewrite_trace_example2.png

このクエリの場合、クエリオプティマイザーでは、上記と同じサマリーが使用されます。サマリーにマテリアライズされた店舗別の部分的売上を結合し、その情報を store のデータと結合して店舗部門を取得して、部門名別に最終的な集計を実行するだけです。

ここでは、この機能を効果的に利用できるクエリの例を 2 つ示したにすぎませんが、実際には多数の事例が考えられます。ここで見てわかるように、これは柔軟性に富み、多くの状況で使用できるので、きわめて高機能なリソースです。

主なユースケース

サマリービューの最も重要なユースケースは、論理データウェアハウスに対してセルフサービスクエリを実行する必要があるユースケースです。この場合のユーザーは、全面的にリアルタイムである必要はないデータをリクエストして、標準的なビューにアクセスします。標準的なビューとは、売上、注文、顧客などのビジネスエンティティに対応するビューであり、補助的なキャッシュビューやキャッシュレポートではありません。

この環境では、サマリービューによってクエリのパフォーマンスが向上し、クエリに関与するデータソースに対する負荷が軽減されます。

../../../../../_images/summary_rewrite_self_service_queries.png

サマリーは、ハイブリッド環境でも大きな効果を示します。その例として、進行中のクラウドへの移行プロセスがあります (以下の図を参照)。このシナリオでは、クラウドへ移行済みのデータと未移行のデータが混在しています。Denodo に用意された抽象化レイヤーにより、クライアントアプリケーションは、この移行に伴う何らかの変化が発生していることを認識せずに、これまでと同様に機能できます。このようなハイブリッド環境では、クラウドデータベースに何らかのサマリーを作成し、クラウドに未移行のデータソースに保存されているデータと結合することが推奨されます。これにより、Virtual DataPort では、オンプレミスデータベースにアクセスしてそこからデータを転送せずに、ほとんどのクエリを実行できます。

../../../../../_images/summary_rewrite_migration_use_case.png

ハイブリッド環境のもう 1 つの例として、マルチクラウドシステムがあります。複数のクラウドプロバイダーにデータを置いている場合、クラウドごとに Denodo サーバーを配置することが推奨されます。これにより、データにできる限り近い場所でデータを処理して、データ転送を最小限にすることができます。このシナリオでは、それぞれの場所にサマリーを作成して、他の場所にあるデータとの共通の組み合わせをサマリーに収めておくことも効果的です。これにより、他のクラウドやオンプレミスのデータへのアクセスを回避できます。

../../../../../_images/summary_rewrite_multicloud.png

キャッシュとサマリー書き換えの比較

サマリーは、従来のキャッシュに比べて以下の点で有利です。

  • 事前計算したデータをユーザー側で使用するには、キャッシュされたビューを明示的に参照する必要があります。クエリオプティマイザーでは、受信したクエリを分析して、可能な場合は必ずサマリーのデータを利用するようにクエリを書き換えます。この処理は透過に実行されるので、人手による操作を必要としません。サマリーの使用を必要とするクエリであることを指定する必要はありません。

  • サマリーの対象は、キャッシュデータソースに限りません。これは、サマリーを作成する際、その特定のデータに最適なデータソースを選択できることを意味します (最大限のコロケーションを目指す場合など)。複数のデータソースに同じデータを保存しておき、状況に応じて最良のオプションがオプティマイザーで選択されるようにすることもできます。

一方、キャッシュのほうが有利な点は以下のとおりです。

  • キャッシュには、更新と管理のオプションが多数用意されています。たとえば、暗黙的キャッシュモード、増分クエリ、アトミックまたは非アトミックな読み込み、選択的な無効化が考えられます。

  • キャッシュでは、それを使用するかどうかを判断する前処理段階を必要としません。したがって、いつも特定のデータに同じ方法でアクセスすることがわかっている場合は、従来のキャッシュを引き続き使用するほうが有利です。これにより、不要なオーバーヘッドの発生を回避できます。

状況に応じて最良の方法を判断するには、論理アーキテクチャをモデル化する際に検出した以下の抽象化レイヤーを確認します (以下の図を参照)。

../../../../../_images/cache_vs_summaries.png
  • 基本レイヤーまたは物理レイヤー: 元のデータセットが格納されています。

  • 統合レイヤー: コンシューマーに公開するビューの作成に必要な、中間状態の変換と結合が格納されています。

  • セマンティックレイヤーまたはビジネスレイヤー: ビジネスエンティティを表すモデルの標準的なビューが格納されています。このレイヤーにあるビューは、多くの場合、データのコンシューマーに公開され、そのコンシューマーはこれらのビューに対して非定型クエリを実行できます。

  • レポートレイヤー: 特定のクライアントに公開する目的で、何らかの計算済みメトリックと最終的なビューで構成した事前定義のレポートが格納されています。

これらのモデル化レイヤーにキャッシュとサマリーのどちらが適しているか、また適していないかが、互いの相違によって決まる様子がわかります。したがって、一般的に以下の点が推奨されます。

  1. ビジネスユーザーやデータサイエンティストなどのデータコンシューマーに公開するモデル (セマンティックレイヤーとビジネスレイヤー) の標準的なビューに対してはサマリーを作成します。このようなデータコンシューマーは、セルフサービス方式でさまざまなビューを結合および集計する非定型クエリを実行する必要があるからです。

  2. 以下のシナリオでは引き続きキャッシュを使用します。

    • すぐに利用できる計算済みメトリックを収めた、事前定義の最終的なレポート (レポートレイヤー)。この場合、投影とフィルターを適用する以外に変換や結合は実行されないので、サマリーの柔軟性は必要ありません。

    • コンシューマーには直接公開しない中間ビュー。この場合、キャッシュされたビューを明示的に参照する必要があることは問題になりません。中間ビューを直接使用するのは開発者のみであり (統合レイヤー)、キャッシュのほうがサマリーよりも多くの更新と管理のオプションを用意しているからです。

サマリーを使用する場合の推奨事項

サマリーを作成する場合は以下の推奨事項を検討します。

  • 以下のいずれかのデータソースにサマリーを保存します。

    1. データの近くにあるデータソース (ファクトテーブルを収めたデータソースなど)

    2. Denodo サーバーの近くにあるデータソース (キャッシュデータソースなど)

  • サマリーの定義のクエリで以下の手順を踏みます。

    • SELECT に count(*) を必ず使用します。さまざまなレベルの集計を使用してクエリを計算する必要があることが考えられるからです。

    • HAVING 条件の使用を避けます。HAVING 条件があることによって、集約度が高いクエリでサマリーを使用できなくなることがあるからです。

  • コストベースの最適化が有効な場合、サマリーの統計情報を収集します。

    • コストオプティマイザーでは、これらの統計情報を判断材料として、サマリーまたは他の代替手段のどちらかが選択されます。

    • サマリーの統計情報を収集するには、サマリーを開いて [Options] タブに移動し、[Statistics] に移動します。

  • インデックスを作成して最高のパフォーマンスが得られるようにすることを検討します。詳細については、「 リモートテーブルまたはサマリーの基盤となるデータベースでのインデックスの作成 」を参照してください。

  • Scheduler タスクを作成して定期的に実行することによって、サマリーを最新の状態に維持します。

  • 単一のビューの使用を採用して、そのビューのすべてのディメンションに複数のファクトテーブルを結び付けているモデルでは、その単一ビューに対するサマリーを必ず作成します。