COUNT DISTINCT 用ビットマップ
ビットマップを使用して、 異なる値の数を計算する。
ビットマップは、配列内の異なる値の数を計算するための便利なツールです。この方法は、従来の Count Distinct と比較して、ストレージスペースを節約し、計算を高速化できます。配列 A が [0, n) の範囲の値を持つと仮定します。(n+7)/8 バイトのビットマップを使用することで、配列内の異なる要素の数を計算できます。これを行うには、すべてのビットを 0 に初期化し、要素の値をビットの添字として設定し、すべてのビットを 1 に設定します。ビットマップ内の 1 の数が、配列内の異なる要素の数です。
従来の Count Distinct
データベースのMPPアーキテクチャは、Count Distinctを使用する際にも詳細なデータを保持できます。しかし、Count Distinct 機能はクエリ処理中に複数のデータシャッフルを必要とし、これによりリソースが多く消費され、データ量が増加するにつれてパフォーマンスが線形に低下します。
以下のシナリオでは、テーブル (dt, page, user_id) の詳細データに基づいて UV を計算します。
| dt | page | user_id |
|---|---|---|
| 20191206 | game | 101 |
| 20191206 | shopping | 102 |
| 20191206 | game | 101 |
| 20191206 | shopping | 101 |
| 20191206 | game | 101 |
| 20191206 | shopping | 101 |
データは以下の図に従って計算される。まず、page と user_id 列でデータをグループ化し、次に処理された結果をカウントします。

注記
図は、2 つの BE ノードで計算された 6 行のデータの概略を示しています。
大規模なデータを扱う場合、複数のシャッフル操作が必要で、計算リソースが大幅に増加する可能性があります。これによりクエリが遅くなります。しかし、ビットマップ技術を使用するこ とで、この問題に対処し、クエリパフォーマンスを向上させることができます。
page でグループ化して uv をカウントします:
select page, count(distinct user_id) as uv from table group by page;
| page | uv |
|---|---|
| game | 1 |
| shopping | 2 |