天天看點

Apache Doris 系列: 基礎篇-使用BitMap函數精準去重(2)

1. 背景

Apache Doris 原有的BitMap函數雖然比較通用, 但在億級别的BitMap大基數并交計算性能較差,主要是由以下兩個原因造成的:

  • 當BitMap的基數過大,大小超過1GB時,網絡或者磁盤的處理時間較長
  • BE節點掃描完資料後傳輸到一個FE節點進行并交計算,給該FE節點帶來壓力,成為處理瓶頸

解決方案:将bitmap列的值按照範圍劃分,不同範圍的值存儲在不同的bucket上,確定在不同bucket的bitmap值是正交的。在查詢的時候,先對不同bucket的bitmap值完成聚合計算,上層的FE節點隻需合并聚合過的資料并輸出即可。如此會極大的改善計算效率,和解決FE節點成為計算瓶頸的問題。

2. 使用指南

增加一列hid, 表示range的範圍,作為hash分桶列

如:

CREATE TABLE ssb.`lineorder_bitmap` (
  `lo_shipmode` varchar(50) NULL COMMENT "user tag",
  `hid` smallint(6) NULL COMMENT "Bucket ID",
  `lo_orderkey` bitmap BITMAP_UNION NULL COMMENT ""
) ENGINE=OLAP
AGGREGATE KEY(`lo_shipmode`, `hid`)
COMMENT "OLAP"
DISTRIBUTED BY HASH(`hid`) BUCKETS 3
PROPERTIES (
"replication_allocation" = "tag.location.default: 1",
"in_memory" = "false",
"storage_format" = "V2",
"disable_auto_compaction" = "false"
);
           

3. 實際查詢效果

3.1 分組去重

select 
lo_shipmode
,orthogonal_bitmap_union_count(lo_orderkey) cnt
from ssb.`lineorder_bitmap` 
group by lo_shipmode
           
Apache Doris 系列: 基礎篇-使用BitMap函數精準去重(2)

查詢結果與上一篇使用COUNT(DISTINCT)的結果一緻。

耗時對比:

COUNT(DISTINCT) : 12秒

bitmap_count(bitmap_union(to_bitmap(lo_orderkey))):6秒

本文使用的orthogonal_bitmap_union_count(lo_orderkey):219毫秒

計算性能得到了極大的提升。

3.2 全量去重

COUNT(DISTINCT) : 2.15秒

bitmap_count(bitmap_union(to_bitmap(lo_orderkey))):3.26秒

本文使用的orthogonal_bitmap_union_count(lo_orderkey):141毫秒

同樣,計算性能也是得到了極大的提升。

繼續閱讀