このトピックでは、長期メトリックの計算を最適化する方法について説明します。
背景情報
eコマース企業がデータウェアハウスを構築したり、ビジネスを分析したりする場合、ある期間の訪問者数、購入者数、通常の購入者数などのメトリックを計算する必要があることがよくあります。 これらのメトリックは、その期間にわたって蓄積されたデータに基づいて計算されます。
select item_id -- The field that indicates the item ID.
,count(distinct visitor_id) as ipv_uv_1d_001
from vistor_item_detail_log
where ds <= ${bdp.system.bizdate}
and ds >=to_char(dateadd(to_date(${bdp.system.bizdate},'yyyymmdd'),-29,'dd'),'yyyymmdd')
group by item_id;毎日大量のログデータが生成される場合、前のSELECT文は多数のマップタスクを必要とします。 99,999を超えるマップタスクが必要な場合、マップタスクは失敗します。
目的
クエリのパフォーマンスへの影響を最小限に抑えながら、長期メトリックを計算します。
長期間に渡って蓄積されるデータの量は膨大である。 システムがデータに基づいてメトリックを計算すると、クエリのパフォーマンスが低下します。 毎日生成されるデータを要約するために使用される中間テーブルを作成することをお勧めします。 これにより、重複するデータレコードを削除し、クエリするデータ量を減らすことができます。
解決策
- 毎日生成されるデータを要約する中間テーブルを作成します。
この例では、item_idフィールドとvisitor_idフィールドのデータに基づいて中間テーブルを作成できます。 以下にコードの例を示します。
insert overwrite table mds_itm_vsr_xx(ds='${bdp.system.bizdate} ') select item_id,visitor_id,count(1) as pv from ( select item_id,visitor_id from vistor_item_detail_log where ds =${bdp.system.bizdate} group by item_id,visitor_id ) a; - 中間テーブルから長期間蓄積されたデータを集計します。
次のコードは、過去30日間の各アイテムの訪問者数を計算します。
select item_id ,count(distinct visitor_id) as uv ,sum(pv) as pv from mds_itm_vsr_xx where ds <= '${bdp.system.bizdate} ' and ds >= to_char(dateadd(to_date('${bdp.system.bizdate} ','yyyymmdd'),-29,'dd'),'yyyymmdd') group by item_id;
影響と考慮事項
前述のソリューションでは、ログデータは毎日重複排除されます。 これにより、計算するデータ量を減らし、クエリのパフォーマンスを向上させることができます。 しかし、システムは、長期間に渡って蓄積されたデータを計算する毎に、複数のパーティションからデータを読み出す必要がある。
この問題を解決するには、複数のパーティションのデータをすべての履歴データを含む1つのパーティションにマージします。 これにより、データを増分的に蓄積し、1つのパーティション内のデータに基づいて長期メトリックを計算できます。
シナリオ
最終日の通常の購入者の数を計算します。 通常の買い手は、特定の期間、たとえば過去30日間に購入を行った買い手です。
select item_id -- The field that indicates the item ID.
,buyer_id as old_buyer_id
from buyer_item_detail_log
where ds < ${bdp.system.bizdate}
and ds >=to_char(dateadd(to_date(${bdp.system.bizdate},'yyyymmdd'),-29,'dd'),'yyyymmdd')
group by item_id
,buyer_id;- ディメンションテーブルを作成して維持します。 このテーブルは、最初の購入時間、最後の購入時間、購入されたアイテムの総数、および購入の総額など、購入者と購入されたアイテムとの間の関係を記録するために使用される。
- ディメンションテーブルのデータを、前日の課金ログのデータで毎日更新します。
- 購入者が通常の購入者であるかどうかを判断するには、購入者の最終購入時刻が過去30日以内であるかどうかを確認します。 これにより、データマッピングの重複が解消され、計算するデータ量が削減されます。