库存拉链表进行了时间折叠,极大降低了表的记录数,也节省了存储空间,但在进行时间展开时会很慢。(所有数据库对不等值关联都慢)
因此,摒弃不等值join才能提速。
-- 创建bitmap表
CREATE TABLE tenant_1800000143_rst.bi_fct_stock_zipper_bitmap (
stock_date roaringbitmap NULL,
stockorg_sk varchar NULL,
stockorg_type varchar NULL,
sku_sk varchar NULL,
stock_qty int4 NULL,
etl_time timestamp NULL
)
-- bitmap查询
select *,rb_and(stock_date,f_daterange('2020-10-01'::date,'2020-10-31'::date))
,rb_to_array(rb_and(stock_date,f_daterange('2020-10-01'::date,'2020-10-31'::date)))
,rb_to_array(stock_date) --2个toarray方便肉眼查看结果,实际不需要
from tenant_1800000143_rst.bi_fct_stock_zipper_bitmap
where stock_date && f_daterange('2020-10-01'::date,'2020-10-31'::date)
其中自定义函数f_daterange是方便求日期序列
create or replace function f_daterange(dt1 date,dt2 date) returns roaringbitmap as $$
declare
rb roaringbitmap;
-- myID integer;
begin
select rb_build_agg(e) into rb from --select
(select to_char(GENERATE_SERIES('2020-10-01'::date,'2020-10-31'::date,'1 day'::interval),'yyyymmdd')::int e) t
;
return rb;
end;
$$ language plpgsql;
将库存拉链表转成了bitmap,其实就是将起止日期2个字段转成起止全部日期的数组,转成int存到roaringbitmap字段,然后通过bit的与、或等操作快速查询。
说明:
- rb_and是求交集
- &&是判断交集
其实pg/gp有更好的方式,daterange:
select stock_date * daterange('2020-10-01', '2020-10-31'),*
from tenant_1800000143_rst.bi_fct_stock_zipper_daterange
where stock_date && daterange('2020-10-01', '2020-10-31')
说明:
- *是求交集
- &&是判断交集