map

使用 map 关键字,SQL 语句会在每个分区内分别执行,然后输出每个分区的执行结果。

适合使用 map 关键字的场景:

  • 场景一:需要在每个分区内进行查询的场景(见 例子 1)

  • 场景二:分组查询计算提升性能(见 例子 2)

对分组数据进行查询和计算时,通常先在各个分区单独计算,然后将结果进行进一步计算以保证最终结果的正确性。如果分区的粒度大于分组的粒度,从而可以确保数据的查询和计算不会跨分区进行,则可添加 map 关键字,避免进一步计算的开销,从而提升查询性能。

注: SQL where 子句中一般不允许使用聚合函数或序列相关函数,原因在于:
  • 若允许则会进行全表扫描计算,无法进行分区剪枝。

  • 但若使用 map 关键字,则允许在 where 子句中使用聚合函数或序列相关函数,在每个分区内部进行指定计算以过滤记录。(见 例子 3)

例子

分区计算

t = table(0..9 as id, take(1 2 3, 10) as qty)
db=database("dfs://rangedb", RANGE, 0 5 10)
pt = db.createPartitionedTable(t, `pt, `id)
pt.append!(t);

select * from pt;
id qty
0 1
1 2
2 3
3 1
4 2
5 3
6 1
7 2
8 3
9 1
select first(id), count(*) from pt map;
first_id count
0 5
5 5

合理使用 map 关键字

合理使用 map 关键字有助于在分组查询和计算时提升性能:

t = table(2022.01.01T00:00:00 + rand(10000000, 10000) as dateTime, rand(1000, 10000) as qty)
if(existsDatabase("dfs://valuedb")) dropDatabase("dfs://valuedb")
db=database("dfs://valuedb", VALUE, 2022.02.01..2022.02.05)
pt = db.createPartitionedTable(t, `pt, `dateTime)
pt.append!(t)

timer(1000) select count(*) from pt group by bar(dateTime, 60)

Time elapsed: 4010.31 ms

timer(1000) select count(*) from pt group by bar(dateTime, 60) map

Time elapsed: 3607.331 ms

跨分区查询

跨分区查询时,指定 map 关键字,以支持在 where 子句中使用聚合函数或者序列相关函数进行条件过滤

t = table(0..9 as id, take(1 2 3, 10) as qty)
db=database("dfs://rangedb", RANGE, 0 5 10)
pt = db.createPartitionedTable(t, `pt, `id)
pt.append!(t);

select * from pt where isDuplicated([id,qty]) = false map;
id qty
0 1
1 2
2 3
3 1
4 2
5 3
6 1
7 2
8 3
9 1