サマリ書き換えによる最適化¶
ここでは、Denodo クエリオプティマイザーでサマリビューを使用してクエリを書き換える方法およびいくつかのベストプラクティスについて説明します。
まず、サマリ書き換えとその仕組みについて理解するために、いくつかの例を取り上げます。これらの例を説明するために、TPC-DS ベンチマークのエンティティを使用します。このベンチマークは、小売製品サプライヤーの意思決定支援機能をモデル化します。使用するエンティティとして、売上情報を収めた store_sales、日付ディメンションを表す date_dim、store などがあります。
以下のように店舗 ID と販売日付 ID および年で集計した総売上を収めたサマリを作成したとします。
SELECT store_sales.ss_store_sk AS store_id
,store_sales.ss_sold_date_sk AS date_id
,date_dim.d_year
,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
GROUP BY store_sales.ss_store_sk
,store_sales.ss_sold_date_sk
,date_dim.d_year
この場合、クエリオプティマイザーでは、この部分的な情報を使用してさまざまなクエリを高速化することを判断できます。以下に 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

このクエリの場合、クエリオプティマイザーでは、サマリにキャッシュされている日付別および店舗別の総売上にフィルタを適用するだけで、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

このクエリの場合、クエリオプティマイザーでは、上記と同じサマリが使用されます。サマリにマテリアライズされた店舗別の部分的売上を結合し、その情報を store のデータと結合して店舗部門を取得して、部門名別に最終的な集計を実行するだけです。
ここでは、この機能を効果的に利用できるクエリの例を 2 つ示したにすぎませんが、実際には多数の事例が考えられます。ここで見てわかるように、これは柔軟性に富み、多くの状況で使用できるので、きわめて高機能なリソースです。
この機能の有効化と無効化¶
スマートクエリアクセラレーションはデフォルトで有効ですが、以下の 3 つのレベルで有効化または無効化ができます。
グローバルレベル: メニュー [Administration] > [Server configuration]、 [Queries optimization] タブ
特定のデータベース: メニュー [Administration] > [Database management]、[Edit Database] ダイアログ
特定のクエリ: パラメータ
'summary_rewrite'='on'|'off'
をクエリの CONTEXT 句に追加
特定のクエリまたはデータベースでこの機能を無効にすると、次の場合に役立つ可能性があります。
サマリが古くなったことを知っている場合。
サマリを使用する場合と使用しない場合とでクエリの性能を比較する場合。
この機能が有効であっても、クエリオプティマイザーが以下の場合に特定のサマリを評価することを考慮します。
'Enable for query rewrite' オプションが選択されている場合。
プロパティ 'Valid for query rewrite' が 'Valid’ の場合。このプロパティは、テーブルが存在し、それが正常に読み込まれた場合のみ Valid になります。
また、サマリビューにはそのマテリアライズドデータを表示する時間がないため、サマリが最新であるようにするために定期的な読み込みを構成することが重要です。サマリ管理の詳細については、「 Managing Summaries 」のセクションを参照してください。
主なユースケース¶
サマリビューの最も重要なユースケースは、論理データウェアハウスに対してセルフサービスクエリを実行する必要があるユースケースです。この場合のユーザーは、全面的にリアルタイムである必要はないデータをリクエストして、標準的なビューにアクセスします。標準的なビューとは、売上、注文、顧客などのビジネスエンティティに対応するビューであり、補助的なキャッシュビューやキャッシュレポートではありません。
この環境では、サマリビューによってクエリのパフォーマンスが向上し、クエリに関与するデータソースに対する負荷が軽減されます。

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

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

キャッシュとサマリ書き換えの比較¶
サマリは、従来のキャッシュに比べて以下の点で有利です。
事前計算したデータをユーザー側で使用するには、キャッシュされたビューを明示的に参照する必要があります。クエリオプティマイザーでは、受信したクエリを分析して、可能な場合は必ずサマリのデータを利用するようにクエリを書き換えます。この処理は透過に実行されるので、人手による操作を必要としません。サマリの使用を必要とするクエリであることを指定する必要はありません。
サマリの対象は、キャッシュデータソースに限りません。これは、サマリを作成する際、その特定のデータに最適なデータソースを選択できることを意味します (最大限のコロケーションを目指す場合など)。複数のデータソースに同じデータを保存しておき、状況に応じて最良のオプションがオプティマイザーで選択されるようにすることもできます。
一方、キャッシュのほうが有利な点は以下のとおりです。
キャッシュには、更新と管理のオプションが多数用意されています。たとえば、暗黙的キャッシュモード、増分クエリ、アトミックまたは非アトミックな読み込み、選択的な無効化が考えられます。
キャッシュでは、それを使用するかどうかを判断する前処理段階を必要としません。したがって、いつも特定のデータに同じ方法でアクセスすることがわかっている場合は、従来のキャッシュを引き続き使用するほうが有利です。これにより、不要なオーバーヘッドの発生を回避できます。
状況に応じて最良の方法を判断するには、論理アーキテクチャをモデル化する際に検出した以下の抽象化レイヤーを確認します (以下の図を参照)。

基本レイヤーまたは物理レイヤー: 元のデータセットが格納されています。
統合レイヤー: コンシューマーに公開するビューの作成に必要な、中間状態の変換と結合が格納されています。
セマンティックレイヤーまたはビジネスレイヤー: ビジネスエンティティを表すモデルの標準的なビューが格納されています。このレイヤーにあるビューは、多くの場合、データのコンシューマーに公開され、そのコンシューマーはこれらのビューに対して非定型クエリを実行できます。
レポートレイヤー: 特定のクライアントに公開する目的で、何らかの計算済みメトリックと最終的なビューで構成した事前定義のレポートが格納されています。
これらのモデル化レイヤーにキャッシュとサマリのどちらが適しているか、また適していないかが、互いの相違によって決まる様子がわかります。したがって、一般的に以下の点が推奨されます。
ビジネスユーザーやデータサイエンティストなどのデータコンシューマーに公開するモデル (セマンティックレイヤーとビジネスレイヤー) の標準的なビューに対してはサマリを作成します。このようなデータコンシューマーは、セルフサービス方式でさまざまなビューを結合および集計する非定型クエリを実行する必要があるからです。
以下のシナリオでは引き続きキャッシュを使用します。
すぐに利用できる計算済みメトリックを収めた、事前定義の最終的なレポート (レポートレイヤー)。この場合、投影とフィルタを適用する以外に変換や結合は実行されないので、サマリの柔軟性は必要ありません。
コンシューマーには直接公開しない中間ビュー。この場合、キャッシュされたビューを明示的に参照する必要があることは問題になりません。中間ビューを直接使用するのは開発者のみであり (統合レイヤー)、キャッシュのほうがサマリよりも多くの更新と管理のオプションを用意しているからです。
サマリを使用する場合の推奨事項¶
サマリを作成する場合は以下の推奨事項を検討します。
以下のいずれかのデータソースにサマリを保存します。
データの近くにあるデータソース (ファクトテーブルを収めたデータソースなど)
Denodo サーバーの近くにあるデータソース (キャッシュデータソースなど)
サマリの定義に使用するクエリでは、以下のことを守ります。
SELECT 句に count(*) を必ず使用します。さまざまなレベルの集計を使用してクエリを計算する必要があることが考えられるからです。
HAVING 条件の使用を避けます。HAVING 条件があることによって、集約度が高いクエリでサマリを使用できなくなることがあるからです。
投影/選択スタックのように、結合のない他のビューの投影/選択のレイヤーとして作成されたビューを派生させた場合、サマリ定義ではクエリで想定される最上位レベルのビューを使用する必要があります。これは、クエリが、投影/選択スタックの集約、または投影/選択スタックとして定義されたビューの結合の集約から構成されている場合、クエリオプティマイザーは、その結合と集約で参照されている最上位レベルのビューを参照しているサマリをマッチングしようとするためです。たとえば、bv_customer 上にビュー customer があり、クエリが bv_customer よりも高い頻度で customer を使用する場合は、サマリ定義で customer を使用する必要があります。
適用する際に、クエリで参照されるビューに対して定義されたプライマリキーと参照制約が存在することを確認してください。これらの情報によって、オプティマイザーがサマリをより多くの状況で利用できるようになります。たとえば、サマリは同等だが追加の結合が含まれる場合に、FK-PK 関係が確保されていれば、カーディナリティは変化しません。
コストベースの最適化が有効な場合、サマリの統計情報を収集します。
コストオプティマイザーでは、これらの統計情報を判断材料として、サマリまたは他の代替手段のどちらかが選択されます。
サマリの統計情報を収集するには、サマリを開いて [Options] タブに移動し、[Statistics] に移動します。
インデックスを作成して最高のパフォーマンスが得られるようにすることを検討します。詳細については、「 リモートテーブルまたはサマリの基盤となるデータベースでのインデックスの作成 」を参照してください。
Denodo Scheduler モジュール を使用して VDPDataLoad を作成し、サマリを最新の状態に保ってください。
単一のビューの使用を採用して、そのビューのすべてのディメンションに複数のファクトテーブルを結び付けているモデルでは、その単一ビューに対するサマリを必ず作成します。
可能であれば、 サマリ推奨ツール を使用してください。この機能はワークロードに基づいて自動でサマリを推奨します。